因为是转载文章 在此标明出处,以前有文章是转的没标明的请谅解,因为有些已经无法找到出处,或者与其它原因。

如有冒犯请联系本人,或删除,或标明出处。

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

几点说明:     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 
    
    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
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
     
     ; 
        }
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
     
     ; 
        }

C# asp.net MVC4 权限设计_User

 

 

 

使用方法:

 

建立一个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中添加几条数据:

C# asp.net MVC4 权限设计_User_02

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

C# asp.net MVC4 权限设计_权限控制_03

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