zoukankan      html  css  js  c++  java
  • asp.net MVC 权限设计

    几点说明:

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

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

        3、通过重载AuthorizeAttribute实现

    数据库设计:

    • image 

    表说明

    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 {

    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>(); 

    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 了

    代码

     

    使用方法:

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

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

    8 publicclass HomeController : BaseController{}
    9  

    演示:

    在controlleraction中添加几条数据:

    image

    根据我们的规则,我们可以知道,未登录的用户可以访问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,结果符合我们的约定;-)

    image

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

    image

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

  • 相关阅读:
    python 使用pyinstaller生成exe,以及编译报错:编译时报错如下:No module named timedeltas not build. If you want import pandas from the source directory, you may need to run 'python setup.py build_ext --inplace --force' to
    Remote desktop manager 如何导入.db配置文件
    C# string怎么转换成泛型T?
    C# 如何在ComboBox输入文字改变时,触发事件?
    C# 检查panel所有的checkbox 是否被选中
    C# bool? 的意思
    WPF: Accessing Databases with Windows Presentation Foundation / WPF链接数据库
    WPF 03
    WPF MVVC 基础
    使用 Topshelf 创建 Windows 服务
  • 原文地址:https://www.cnblogs.com/shijiehaiyang/p/12905328.html
Copyright © 2011-2022 走看看