夜鹰教程网-程序员的加油站
 当前位置:文章中心 >> Asp.net专题(WCF/WPF/WF)
基于将角色与controller、action相关联来判断用户是否有权
夜鹰教程网 来源:www.yyjcw.com 日期:2017-10-27 10:44:47
基于将角色与controller、action相关联来判断用户是否有权

因为好的文章,以前只想收藏,但连接有时候会失效,所以现在碰到好的直接转到自己这里。

原文 出处http://www.cnblogs.com/xiaoqi/archive/2010/01/07/1641570.html

几点说明:

 

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

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

    3、通过重载AuthorizeAttribute实现

 

数据库设计:

4.png 

  •  

表说明

 

ControllerAction 

  1.     Name是controller的名称

  2.     IsController是指是否是controller,如果为false,表示存的是action,那么controllerName字段就派上用场了

  3.     IsAllowedNoneRoles是指是否允许没有权限的人访问

  4.     IsAllowedAllRoles是指是否允许有角色的人访问

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

 

 

ControllerActionRole

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

角色NameControllNameIsAllowedIsController
   AAdminHomefalsefalse
   AHomeNulltruetrue

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

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

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

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

 

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

 

判断是否有权限的设定

 

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

复制代码

1 public class UserAuthorizeAttribute : AuthorizeAttribute
2    {
3
4     public override void 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      return true;
17 }
18
19  

复制代码

 

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

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

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

 

复制代码

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

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

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

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

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

           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))
                   {
                       
return false;
                   }
               }
           }

           
// 查找允许访问的角色列表
           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))
                   {
                       
return true;
                   }
               }
           }

           
return false;
       }

复制代码

 

 

 

使用方法:

 

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

复制代码

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

复制代码

 

 

演示:

 

在controlleraction中添加几条数据:

3.png

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

我们看对应的Action:

复制代码

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

复制代码

 

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

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

2.png

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

1.png

复制链接 网友评论 收藏本文 关闭此页
上一条: 浅析c#权限管理  下一条: 网页渲染以及其重要性
夜鹰教程网成立于2008年,目前已经运营了将近 13 年,发布了大量关于 html5/css3/C#/asp.net/java/python/nodejs/mongodb/sql server/android/javascript/mysql/mvc/easyui/vue/echarts原创教程。 我们一直都在坚持的是:认证负责、一丝不苟、以工匠的精神来打磨每一套教程,让读者感受到作者的用心。我们默默投入的时间,确保每一套教程都是一件作品,而不是呆板的文字和视频! 目前我们推出在线辅导班试运营,模式为一对一辅导,教学工具为QQ。我们的辅导学科包括 java 、android原生开发、webapp开发、商城开发、C#和asp.net开发,winform和物联网开发、web前端开发,但不仅限于此。 普通班针对的是国内学员,例如想打好基础的大学生、想转行的有志青年、想深入学习的程序员、想开发软件的初学者或者业余爱好者等。 就业办针对即将毕业上岗的大四学生,或者打算转行的初级开发工程师。 留学生班针对的是在欧美、加拿大、澳洲、日本、韩国、新加坡等地留学的中国学子,目的是让大家熟练地掌握编程技能,按时完成老师布置的作业,并能顺利地通过考试。 详细咨询QQ:1416759661   夜鹰教程网  基于角色的权限管理系统(c-s/b-s)。
  夜鹰教程网  基于nodejs的聊天室开发视频教程
  夜鹰教程网  Git分布式版本管理视频教程
  夜鹰教程网  MVC+EasyUI视频教程
  夜鹰教程网  在线考试系统视频教程
  夜鹰教程网  MongoDB视频教程。
  夜鹰教程网 Canvas视频教程
  夜鹰教程网 报表开发视频教程
  热点推荐
表单提交中get和post方式的区别有…
解决ASP中UTF-8与GB2312编码转换乱…
asp数组中REDIM的用法(动态数组)…
生成html的新方法ASP
ASP字符串函数大全
ASP生成Word文件的代码
ASP中Randomize随机函数的使用
十天学会ASP教程之第一天:安装调…
自定义的asp日期格式化函数
防范ASP网站漏洞的八大法则之一
十天学会ASP教程之第二天:表单传…
asp中关于从utf8页面到gb2312页面…
ASP教程:实现长文章分页功能
IIS6架设网站的问题总结
五分钟打开 allow_url_fopen 的最…
  最近更新
C# Json数据中的特殊字符导致页面…
博客园是有开发博客查询相关的接口…
C#里面的ref和out区别
C#调用API让声卡发出声音
.NET使用反射读取用户自定义的枚举…
.net操作SqlServer数据库增删改查…
如何将WCF服务部署到远程服务器
对WebApi 实现服务端信息的监控
用WCF生成Restful风格的接口返回 …
只有一个地址如何调用WCF服务
WCF简介
搭一个简单的wcf服务
WCF配置说明
WCF传输的数据量过大问题的解决方…
asp.net大文件分块上传文件秒传断…

关于我们 | 网站建设 | 技术辅导 | 常见问题 | 联系我们 | 友情链接

夜鹰教程网 版权所有 www.yyjcw.com All rights reserved 备案号:蜀ICP备08011740号3