几点说明:

1、该权限系统是个网站用的,用户简单,因此不涉及到部门这些信息

2、基于将角色与controller、action相关联来判断用户是否有权

3、通过重载AuthorizeAttribute实现

数据库设计:

表说明

ControllerAction

  1. Name是controller的名称
  2. IsController是指是否是controller,如果为false,表示存的是action,那么controllerName字段就派上用场了
  3. IsAllowedNoneRoles是指是否允许没有权限的人访问
  4. IsAllowedAllRoles是指是否允许有角色的人访问

IsAllowedNoneRoles,IsAllowedAllRoles实现了允许所有人访问以及允许所有注册用户访问:),并且我们约定,IsAllowedNoneRoles具有最高的优先级,其次是IsAllowedAllRoles,然后才是ControllerActionRole中定义的规则

 

 

ControllerActionRole

IsAllowed表示该action或者controller是否允许访问,加入表中有两条记录

角色 Name ControllName IsAllowed IsController
   A Admin Home false false
   A Home Null true true

这里约定分两个层次来判断权限:

第一条记录:表示A角色不能访问 Home/admin

第二条记录:表示A角色可以访问Controller下的所有方法

到底能不能访问呢?其实,我们以action为准,如果定义了action,我们直接从action的约定来判断,因此这里判断A不能访问Home/admin

 其他几张表一看就明白,不再多说

判断是否有权限的设定

1、获取controller,action,以及存放在session中的用户信息

1 publicclass UserAuthorizeAttribute : AuthorizeAttribute
2 {
3
4 publicoverridevoid OnAuthorization(AuthorizationContext filterContext)
5 {
6 var user = filterContext.HttpContext.Session["CurrentUser"] as User;
7 var controller = filterContext.RouteData.Values["controller"].ToString();
8 var action = filterContext.RouteData.Values["action"].ToString();
9 var isAllowed =this.IsAllowed(user, controller, action);
10
11 if (!isAllowed)
12 {
13 filterContext.RequestContext.HttpContext.Response.Write("无权访问");
14 filterContext.RequestContext.HttpContext.Response.End();
15 }
16
17 }
18
19 ……
20
21 }
22  

2、检索数据库ControllerAction表中有没有Name为第一步中controller 的记录,如果没有,我们约定这个controller是不需要进行权限控制的,如果有的话,进入第三步

3、前面提到了,我们约定对权限的控制分为两个层次,controller和action层次,如果同时定义了,以action为准。因此,我们需要判断是否在数据库中有action的记录,如果有,进入4,无,进入5

1 bool IsAllowed(User user, string controllerName, string actionName)
2 {
3 var service = ServiceLoader.LoadService<ToySpirit.IToySpiritService.IControllerActionService>();
4
5 // 获取对应的controller
6   var controller = service.GetSingleByExpression(c => c.Name == controllerName && c.IsController);
7 if (controller !=null)
8 {
9 // 获取对应的action
10   var controllerAction = service.GetSingleByFunc(c => c.Name == actionName && c.IsController ==false&& c.ControllerName == controllerName);
11
12 return controllerAction ==null?this.isAllowed(user, controller) : this.isAllowed(user, controllerAction);
13 }
14
15 // 没有定义controller的权限,表示无需权限控制
16  returntrue;
17 }
18
19  

4、如果有action的记录,那么我们首先判断controllerAction 拒绝哪些角色访问,如果用户有角色在这里面,很遗憾,就不能访问了;然后判断controllerAction 允许哪些角色访问,如果用户的角色在这里面,就可以访问了

注:这里很有可能用户有多个角色,比如A,B,C,如果A不能访问controllerAction,那么很遗憾,用户不能访问,尽管角色B,C可能可以访问该controllerAction

5、没有action的记录,自然就检查controller对应的controllerAction 了

代码

4、5判断的代码是一样的,如下:

privatebool isAllowed(User user, ControllerAction controllerAction)
{
// 允许没有角色的:也就是说允许所有人,包括没有登录的用户
if (controllerAction.IsAllowedNoneRoles)
{
returntrue;
}

// 允许所有角色:只要有角色,就可以访问
if (controllerAction.IsAllowedAllRoles)
{
return user.Roles.Count >0;
}

if (user ==null|| user.Roles.Count ==0)
{
returnfalse;
}

// 选出action对应的角色
var roles = controllerAction.ControllerActionRoles.Select(ca => ca.Role).ToList();
if (roles.Count ==0)
{
// 角色数量为0,也就是说没有定义访问规则,默认允许访问
returntrue;
}

var userHavedRolesids = user.Roles.Select(r => r.ID).ToList();

// 查找禁止的角色
var notAllowedRoles = controllerAction.ControllerActionRoles.FindAll(r => r.IsAllowed ==false).Select(ca => ca.Role).ToList();
if (notAllowedRoles.Count >0)
{
foreach (Role role in notAllowedRoles)
{
// 用户的角色在禁止访问列表中,不允许访问
if (userHavedRolesids.Contains(role.ID))
{
returnfalse;
}
}
}

// 查找允许访问的角色列表
var allowRoles = controllerAction.ControllerActionRoles.FindAll(r => r.IsAllowed).Select(ca => ca.Role).ToList();
if (allowRoles.Count >0)
{
foreach (Role role in allowRoles)
{
// 用户的角色在访问的角色列表
if (userHavedRolesids.Contains(role.ID))
{
returntrue;
}
}
}

returnfalse;
}

 

使用方法:

建立一个basecontroller,使用我们定义好的UserAuthorize,然后所有的controller继承basecontroller就可以了

1 ///<summary>
2 /// 控制基类
3 ///</summary>
4   [UserAuthorize]
5 publicabstractclass BaseController : Controller
6 {}
7
8 publicclass HomeController : BaseController{}
9  

演示:

在controlleraction中添加几条数据:

根据我们的规则,我们可以知道,未登录的用户可以访问Home/Public,其他几个页面则不能访问

我们看对应的Action:

1 publicvoid ViewPage()
2 {
3 Response.Write("View");
4 }
5 publicvoid Public()
6 {
7 Response.Write("Public");
8 }
9 publicvoid Delete()
10 {
11 Response.Write("Delete");
12 }

访问Home/Public,如果有权限,那么显示“Public“,否则显示”无权访问”

未登录用户访问Home/Public,结果符合我们的约定;-)

未登录用户访问Home/ViewPage,按约定应该显示错误信息

查看 asp.net MVC 权限设计(续)

asp.net MVC 权限设计相关推荐

  1. asp.net MVC 权限设计(续)

    asp.net MVC 权限设计一文中没有demo放出来,应大家的要求,这里补充上文并放出demo. 几点说明: 1.基于将角色与controller.action相关联来判断用户是否有权 2.通过自 ...

  2. Asp.net MVC权限设计思考 (一)数据库建库部分

    目前各类的权限设计已经困扰了我们好久,对于MVC,下面我将通过ActionFilter来扩展我们的权限认证,以下示例是从我的一个课程中心项目中提取出来,希望对各位初学者起到抛砖引玉的作用. 下面首先来 ...

  3. 自定义AuthorizeAttribute实现MVC权限设计

    文本为您介绍:自定义AuthorizeAttribute实现MVC权限设计,主要是通过将角色与controller.action等参数关联进行用户权限判断,然后通过自定义AuthorizeAttrib ...

  4. 关于ASP.NET MVC开发设计中出现的问题与解决方案汇总 【持续更新】

    关于ASP.NET MVC开发设计中出现的问题与解决方案汇总 [持续更新] 参考文章: (1)关于ASP.NET MVC开发设计中出现的问题与解决方案汇总 [持续更新] (2)https://www. ...

  5. asp.net mvc 权限过滤和单点登录(禁止重复登录)

    1.权限控制使用controller和 action来实现,权限方式有很多种,最近开发项目使用控制控制器方式实现代码如下 /// <summary>/// 用户权限控制/// </s ...

  6. 【转】ASP.NET MVC实现权限控制

    这篇分享一下 ASP.NET MVC权限控制.也就是说某一用户登录之后,某一个用户是否有权限访问Controller,Action(操作),视图等 想实现这些功能,需要在数据库创建好几个表:[User ...

  7. Asp.net MVC 多语言问题的解决方案

    上篇文章我们就Asp.net MVC权限问题做了一个较为全面的解决方案,这篇我们就多语言问题进行探讨. 全球化 在IT行业,具有全球化和本地化特性的计算机软件,可以适应不同的语言,地区差异和目标市场的 ...

  8. 使用asp.net mvc开发应用程序,页面中的page.IsPostback还有用处吗?

    本来我对asp.net mvc也研究了一段时间了,我也使用了asp.net mvc开发了两套应用程序,虽然都不是什么大的系统. 今天也想特别提出一个疑问,不知道是我不知道呢,还是本身很难实现在asp. ...

  9. Pro ASP.NET MVC 3 Framework 译文(一)

    ASP.NET MVC3简介 2011年10月22日 12:49 对于使用微软平台的开发人员来说,ASP.NET MVC框架有了一个根本的转变.它强调"干净的"体系.设计模式.可测 ...

最新文章

  1. IO流(文本文件读取练习)
  2. 用ajax控件作的高级搜索
  3. 互联网亿级日志实时分析平台,一个码农半小时就可以搞定,只因ELK
  4. R语言XML格式数据导入与处理
  5. 机器学习理论与实战(十五)概率图模型03
  6. 这不是商业互吹,是学习的宝藏
  7. 子类怎么继承父类方法中的变量_关于继承的那些事!
  8. 集结六大行业领袖,「数据科学家」新课全球首发!
  9. Axure动态面板设置 2020-11-06
  10. java pdf tiff_关于java:使用iText将tiff文件转换为pdf文件时出现异常
  11. 移动硬盘打开文件突然变得很卡
  12. 超简洁又强大的幻灯片JS、CSS代码,兼容性强
  13. 【Tableau server 8.0】Tableau server 考试真题回顾总结
  14. 迪文屏CRC16校验
  15. Linux的开源操作系统
  16. C/C++编程学习:百行代码实现小游戏(剪刀石头布)
  17. JRebel LS client not configured解决方案
  18. druid安装与案例
  19. APK获取包名的办法
  20. 重磅!中国商业联合会专家委员会商贸物流与供应链智库成立在即

热门文章

  1. SecureCRT 端口转发连接服务器
  2. itop修改附件上传大小限制
  3. WinSock网络编程基础(3)server
  4. JavaScript正则表达式快速判断技巧
  5. android 中文件操作模式
  6. 重载(Overload )和覆写(override)的理解及区别
  7. 微软针对中国中小企业推出打包服务
  8. vue项目通过命令行传参实现多环境配置(基于@vue/cli)
  9. 虚拟机里Centos7的IP地址查看方法
  10. Wdatepicker日期控件的使用指南