• 一个简单的ASP.NET MVC下的权限方案


    偶然看到博客园里 JadePeng 的 一篇关于ASP.NET MVC下的权限设计的旧文 http://www.cnblogs.com/xiaoqi/archive/2010/01/07/1641570.html,该权限设计中用到5个数据表,利用数据库中的Controller和action记录进行权限判断。

    多年前我在一个web form的 web项目里用过类似的方式,当然那里没有controller和action, 主要是将判断函数放在基类里,在页面.cs里调用此函数作为权限判断。

    这里提出一个使用XML+数据库+ session(cookie) 的权限方案,旨在简单易懂易用,设计粗劣,大家有兴趣改进。

    因为个人觉得在普通的小系统里,角色role是有限的,一个系统里的controller和action总归也是有限的(1K以内?呵呵)。所以我用XML而不是数据库来记录这些。

    几点说明:

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

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

        3、通过重载AuthorizeAttribute实现

        ----- 前3项COPY自http://www.cnblogs.com/xiaoqi/archive/2010/01/07/1641570.html 

        4. 权限的设定保存于XML之中,权限在用户登录后存储于session(理论上cookie也可以),用户登录后判断权限无需查询数据库。

    数据库设计:

        2个数据表,User 和 UserRole,字段简单,不多做解释了。

     

    相关XML

    1. Role.xml --- 记录系统的所有角色,比如

    Role.xml
    <?xml version="1.0" encoding="utf-8"?>
    <role>
      <item>
        <name>Guest</name>
        <desciption></desciption>
      </item>
      <item>
        <name>Admin1</name>
        <desciption></desciption>
      </item>
      <item>
        <name>RegisterUser</name>
        <desciption>注册用户</desciption>
      </item>
    </role>

    2. Permission.xml ---- 记录系统所有的操作权限 --- 在MVC里的权限是用Controller和action来判定的,此XML的作用在于提供给UI界面添加、管理系统的所有权限。

        节点说明 -- module 节点为controller的名称,一个controller下的action 和 controller本身组成 permission节点

    Permission.xml
      1 <?xml version="1.0" encoding="utf-8"?>
      2 <permissionRoot>
      3   <module name="Home">
      4     <permission>
      5       <controller>Home</controller>
      6       <action>Index</action>
      7     </permission>
      8     <permission>
      9       <controller>Home</controller>
     10       <action>KeepAlive</action>
     11     </permission>
     12     <permission>
     13       <controller>Home</controller>
     14       <action>About</action>
     15     </permission>
     16   </module>
     17   <module name="Account">
     18     <permission>
     19       <controller>Account</controller>
     20       <action>LogOn</action>
     21     </permission>
     22     <permission>
     23       <controller>Account</controller>
     24       <action>LogOff</action>
     25     </permission>
     26     <permission>
     27       <controller>Account</controller>
     28       <action>Register</action>
     29     </permission>
     30     <permission>
     31       <controller>Account</controller>
     32       <action>Lock</action>
     33     </permission>
     34   </module>
     35   <module name="General">
     36     <permission>
     37       <controller>General</controller>
     38       <action>SearchResults</action>
     39     </permission>
     40   </module>
     41   <module name="Book">
     42     <permission>
     43       <controller>Book</controller>
     44       <action>Update</action>
     45     </permission>
     46     <permission>
     47       <controller>Book</controller>
     48       <action>Novel</action>
     49     </permission>
     50     <permission>
     51       <controller>Book</controller>
     52       <action>History</action>
     53     </permission>
     54     <permission>
     55       <controller>Book</controller>
     56       <action>Live</action>
     57     </permission>
     58     <permission>
     59       <controller>Book</controller>
     60       <action>Blog</action>
     61     </permission>
     62     <permission>
     63       <controller>Book</controller>
     64       <action>Military</action>
     65     </permission>
     66     <permission>
     67       <controller>Book</controller>
     68       <action>Other</action>
     69     </permission>
     70     <permission>
     71       <controller>Book</controller>
     72       <action>Detail</action>
     73     </permission>
     74     <permission>
     75       <controller>Book</controller>
     76       <action>HotBook</action>
     77     </permission>
     78     <permission>
     79       <controller>Book</controller>
     80       <action>LatestUpdateBook</action>
     81     </permission>
     82     <permission>
     83       <controller>Book</controller>
     84       <action>Index</action>
     85     </permission>
     86     <permission>
     87       <controller>Book</controller>
     88       <action>GetData</action>
     89     </permission>
     90     <permission>
     91       <controller>Book</controller>
     92       <action>GetBooks</action>
     93     </permission>
     94   </module>
     95   <module name="Books">
     96   <permission>
     97     <controller>Books</controller>
     98     <action>Management</action>
     99   </permission>
    100   <permission>
    101     <controller>Books</controller>
    102     <action>CreateBook</action>
    103   </permission>
    104   <permission>
    105     <controller>Books</controller>
    106     <action>Edit</action>
    107   </permission>
    108   <permission>
    109     <controller>Books</controller>
    110     <action>Lock</action>
    111   </permission>
    112   <permission>
    113       <controller>Books</controller>
    114       <action>Delete</action>
    115     </permission>
    116   </module>
    117   <module name="Role">
    118   <permission>
    119     <controller>Role</controller>
    120     <action>Management</action>
    121   </permission>
    122   <permission>
    123     <controller>Role</controller>
    124     <action>AddRole</action>
    125   </permission>
    126   <permission>
    127     <controller>Role</controller>
    128     <action>EditRolePermission</action>
    129   </permission>
    130   <permission>
    131       <controller>Role</controller>
    132       <action>Delete</action>
    133     </permission>
    134   </module>
    135   <module name="User">
    136     <permission>
    137       <controller>User</controller>
    138       <action>Management</action>
    139     </permission>
    140     <permission>
    141       <controller>User</controller>
    142       <action>CreateUser</action>
    143     </permission>
    144     <permission>
    145       <controller>User</controller>
    146       <action>Edit</action>
    147     </permission>
    148     <permission>
    149       <controller>User</controller>
    150       <action>Delete</action>
    151     </permission>
    152     <permission>
    153       <controller>User</controller>
    154       <action>AddToRole</action>
    155     </permission>
    156     <permission>
    157       <controller>User</controller>
    158       <action>RemoveFromRole</action>
    159     </permission>
    160     <permission>
    161       <controller>User</controller>
    162       <action>CheckUserName</action>
    163     </permission>
    164   </module>
    165   <module name="Config">
    166     <permission>
    167       <controller>Config</controller>
    168       <action>Category</action>
    169     </permission>
    170     <permission>
    171       <controller>Config</controller>
    172       <action>Property</action>
    173     </permission>
    174     <permission>
    175       <controller>Config</controller>
    176       <action>LinkFrom</action>
    177     </permission>
    178     <permission>
    179       <controller>Config</controller>
    180       <action>AddCategoryItem</action>
    181     </permission>
    182     <permission>
    183       <controller>Config</controller>
    184       <action>DeleteCategoryItem</action>
    185     </permission>
    186     <permission>
    187       <controller>Config</controller>
    188       <action>AddPropertyItem</action>
    189     </permission>
    190     <permission>
    191       <controller>Config</controller>
    192       <action>DeletePropertyItem</action>
    193     </permission>
    194     <permission>
    195       <controller>Config</controller>
    196       <action>AddLinkFromItem</action>
    197     </permission>
    198     <permission>
    199       <controller>Config</controller>
    200       <action>DeleteLinkFromItem</action>
    201     </permission>
    202   </module>
    203 </permissionRoot>

    3.RolePermission.xml ---- 记录系统内所有角色的权限记录。结构如下:

     
    RolePermission.xml
    <?xml version="1.0" encoding="utf-8"?>
    <permissionRoot>
      <role name="Guest">
        <permission>
          <controller>Home</controller>
          <action>Index</action>
        </permission>
        <permission>
          <controller>Home</controller>
          <action>KeepAlive</action>
        </permission>
        <permission>
          <controller>Home</controller>
          <action>About</action>
        </permission>
        <permission>
          <controller>Account</controller>
          <action>LogOn</action>
        </permission>
        <permission>
          <controller>Account</controller>
          <action>LogOff</action>
        </permission>
        <permission>
          <controller>Account</controller>
          <action>Register</action>
        </permission>
        <permission>
          <controller>Account</controller>
          <action>Lock</action>
        </permission>
        <permission>
          <controller>General</controller>
          <action>SearchResults</action>
        </permission>
        <permission>
          <controller>Book</controller>
          <action>Update</action>
        </permission>
        <permission>
          <controller>Book</controller>
          <action>Novel</action>
        </permission>
        <permission>
          <controller>Book</controller>
          <action>History</action>
        </permission>
        <permission>
          <controller>Book</controller>
          <action>Live</action>
        </permission>
        <permission>
          <controller>Book</controller>
          <action>Blog</action>
        </permission>
        <permission>
          <controller>Book</controller>
          <action>Other</action>
        </permission>
        <permission>
          <controller>Book</controller>
          <action>Detail</action>
        </permission>
        <permission>
          <controller>Book</controller>
          <action>HotBook</action>
        </permission>
        <permission>
          <controller>Book</controller>
          <action>LatestUpdateBook</action>
        </permission>
        <permission>
          <controller>Book</controller>
          <action>Index</action>
        </permission>
        <permission>
          <controller>Book</controller>
          <action>GetData</action>
        </permission>
        <permission>
          <controller>Book</controller>
          <action>GetBooks</action>
        </permission>
      </role>
      <role name="RegisterUser">
        <permission>
          <controller>Home</controller>
          <action>Index</action>
        </permission>
        <permission>
          <controller>Home</controller>
          <action>KeepAlive</action>
        </permission>
        <permission>
          <controller>Home</controller>
          <action>About</action>
        </permission>
        <permission>
          <controller>Account</controller>
          <action>LogOn</action>
        </permission>
        <permission>
          <controller>Account</controller>
          <action>LogOff</action>
        </permission>
        <permission>
          <controller>Account</controller>
          <action>Register</action>
        </permission>
        <permission>
          <controller>Account</controller>
          <action>Lock</action>
        </permission>
        <permission>
          <controller>General</controller>
          <action>SearchResults</action>
        </permission>
        <permission>
          <controller>Book</controller>
          <action>Update</action>
        </permission>
        <permission>
          <controller>Book</controller>
          <action>Novel</action>
        </permission>
        <permission>
          <controller>Book</controller>
          <action>History</action>
        </permission>
        <permission>
          <controller>Book</controller>
          <action>Live</action>
        </permission>
        <permission>
          <controller>Book</controller>
          <action>Blog</action>
        </permission>
        <permission>
          <controller>Book</controller>
          <action>Military</action>
        </permission>
        <permission>
          <controller>Book</controller>
          <action>Other</action>
        </permission>
        <permission>
          <controller>Book</controller>
          <action>Detail</action>
        </permission>
        <permission>
          <controller>Book</controller>
          <action>HotBook</action>
        </permission>
        <permission>
          <controller>Book</controller>
          <action>LatestUpdateBook</action>
        </permission>
        <permission>
          <controller>Book</controller>
          <action>Index</action>
        </permission>
        <permission>
          <controller>Book</controller>
          <action>GetData</action>
        </permission>
        <permission>
          <controller>Book</controller>
          <action>GetBooks</action>
        </permission>
      </role>
      <role name="Admin1">
        <permission>
          <controller>Home</controller>
          <action>Index</action>
        </permission>
        <permission>
          <controller>Home</controller>
          <action>KeepAlive</action>
        </permission>
        <permission>
          <controller>Home</controller>
          <action>About</action>
        </permission>
        <permission>
          <controller>Account</controller>
          <action>LogOn</action>
        </permission>
        <permission>
          <controller>Account</controller>
          <action>LogOff</action>
        </permission>
        <permission>
          <controller>Account</controller>
          <action>Register</action>
        </permission>
        <permission>
          <controller>Account</controller>
          <action>Lock</action>
        </permission>
        <permission>
          <controller>General</controller>
          <action>SearchResults</action>
        </permission>
        <permission>
          <controller>Book</controller>
          <action>Update</action>
        </permission>
        <permission>
          <controller>Book</controller>
          <action>Novel</action>
        </permission>
        <permission>
          <controller>Book</controller>
          <action>History</action>
        </permission>
        <permission>
          <controller>Book</controller>
          <action>Live</action>
        </permission>
        <permission>
          <controller>Book</controller>
          <action>Blog</action>
        </permission>
        <permission>
          <controller>Book</controller>
          <action>Military</action>
        </permission>
        <permission>
          <controller>Book</controller>
          <action>Other</action>
        </permission>
        <permission>
          <controller>Book</controller>
          <action>Detail</action>
        </permission>
        <permission>
          <controller>Book</controller>
          <action>HotBook</action>
        </permission>
        <permission>
          <controller>Book</controller>
          <action>LatestUpdateBook</action>
        </permission>
        <permission>
          <controller>Book</controller>
          <action>Index</action>
        </permission>
        <permission>
          <controller>Book</controller>
          <action>GetData</action>
        </permission>
        <permission>
          <controller>Book</controller>
          <action>GetBooks</action>
        </permission>
        <permission>
          <controller>Books</controller>
          <action>Management</action>
        </permission>
        <permission>
          <controller>Books</controller>
          <action>CreateBook</action>
        </permission>
        <permission>
          <controller>Books</controller>
          <action>Edit</action>
        </permission>
        <permission>
          <controller>Books</controller>
          <action>Lock</action>
        </permission>
        <permission>
          <controller>Books</controller>
          <action>Delete</action>
        </permission>
        <permission>
          <controller>Role</controller>
          <action>Management</action>
        </permission>
        <permission>
          <controller>Role</controller>
          <action>AddRole</action>
        </permission>
        <permission>
          <controller>Role</controller>
          <action>EditRolePermission</action>
        </permission>
        <permission>
          <controller>Role</controller>
          <action>Delete</action>
        </permission>
        <permission>
          <controller>User</controller>
          <action>Management</action>
        </permission>
        <permission>
          <controller>User</controller>
          <action>CreateUser</action>
        </permission>
        <permission>
          <controller>User</controller>
          <action>Edit</action>
        </permission>
        <permission>
          <controller>User</controller>
          <action>Delete</action>
        </permission>
        <permission>
          <controller>User</controller>
          <action>AddToRole</action>
        </permission>
        <permission>
          <controller>User</controller>
          <action>RemoveFromRole</action>
        </permission>
        <permission>
          <controller>User</controller>
          <action>CheckUserName</action>
        </permission>
        <permission>
          <controller>Config</controller>
          <action>Category</action>
        </permission>
        <permission>
          <controller>Config</controller>
          <action>Property</action>
        </permission>
        <permission>
          <controller>Config</controller>
          <action>LinkFrom</action>
        </permission>
        <permission>
          <controller>Config</controller>
          <action>AddCategoryItem</action>
        </permission>
        <permission>
          <controller>Config</controller>
          <action>DeleteCategoryItem</action>
        </permission>
        <permission>
          <controller>Config</controller>
          <action>AddPropertyItem</action>
        </permission>
        <permission>
          <controller>Config</controller>
          <action>DeletePropertyItem</action>
        </permission>
        <permission>
          <controller>Config</controller>
          <action>AddLinkFromItem</action>
        </permission>
        <permission>
          <controller>Config</controller>
          <action>DeleteLinkFromItem</action>
        </permission>
      </role>
    </permissionRoot>

    流程

    流程较为简单,故文字说明。

    1.User表用户登录的同时,从UserRole表中查询出用户所拥有的角色,然后在RolePermission.xml里查询得到所拥有角色的所有权限permission列表,每个permission格式为 controller_action,组成一个list,踢出重复项,再转为string,保存于session之中。session 同时保存用户名

    2.新建一个filter: UserAuthorizeAttribute,继承AuthorizeAttribute, 重写OnAuthorization。在此方法体内 做判断,如果用户的permission列表里包含当前的controller,action,验证通过,否则反之。

    3.对于未登陆用户,默认采用Guest角色的权限。(视系统需要而定)

    主要代码

    1.UserAuthorizeAttribute.cs

    View Code
      1 namespace Clover.Net.Web.Code.Filters
      2 {
      3     /// <SUMMARY> 
      4     /// 自定义AuthorizeAttribute 
      5     /// </SUMMARY> 
      6     public class UserAuthorizeAttribute : AuthorizeAttribute
      7     {
      8         private PermissionRepository _permissionRepository = new PermissionRepository();
      9 
     10         public override void OnAuthorization(AuthorizationContext filterContext)
     11         {
     12             string rolePermissionXml = filterContext.HttpContext.Server.MapPath("/Config/RolePermission.xml");
     13             var user = filterContext.HttpContext.Session["user_Name"];
     14             var permissions = filterContext.HttpContext.Session["user_Permissions"];
     15 
     16             List<string> user_Permissions = new List<string>();
     17 
     18             if (user != null || permissions != null)
     19             {
     20                 string[] userTotalPermissions = permissions.ToString().Split(',');
     21                 foreach (var per in userTotalPermissions)
     22                 {
     23                     user_Permissions.Add(per);
     24                 }
     25             }
     26             //用户为空,赋予Guest  and set up the session
     27             else
     28             {
     29                 string guestTotalPermissions = string.Empty;
     30                 List<PermissionItem> permissionList = _permissionRepository.CurrentRolePermissions(rolePermissionXml, "Guest");
     31                 foreach (var per in permissionList)
     32                 {
     33                     guestTotalPermissions = guestTotalPermissions + "," + per.Controller + "_" + per.Action;
     34                 }
     35                 filterContext.HttpContext.Session["user_Name"] = "Guest";
     36                 filterContext.HttpContext.Session["user_Permissions"] = guestTotalPermissions;
     37 
     38                 string[] userTotalPermissions = guestTotalPermissions.ToString().Split(',');
     39                 foreach (var per in userTotalPermissions)
     40                 {
     41                     user_Permissions.Add(per);
     42                 }
     43             }
     44 
     45             string controller = filterContext.RouteData.Values["controller"].ToString();
     46             string action = filterContext.RouteData.Values["action"].ToString();
     47 
     48             string id = String.Empty;
     49             if (filterContext.RouteData.Values["id"] != null)
     50             {
     51                id = filterContext.RouteData.Values["id"].ToString();
     52             }
     53             var isAllowed = this.IsAllowed(controller, action, user_Permissions);
     54 
     55             if (!isAllowed)
     56             {
     57                 //filterContext.RequestContext.HttpContext.Response.Write("无权访问");
     58                 //filterContext.RequestContext.HttpContext.Response.End();
     59 
     60                 //filterContext.RequestContext.HttpContext.Response.Redirect("../Account/LogOn");
     61 
     62                 string returnUrl = String.Empty;
     63                 if (String.IsNullOrEmpty(id))
     64                 {
     65                     returnUrl = "/" + controller + "/" + action;
     66                 }
     67                 else
     68                 {
     69                     returnUrl = "/" + controller + "/" + action + "/" + id;
     70                 }
     71 
     72                 filterContext.Controller.ViewData["ReturnUrl"] = returnUrl;
     73 
     74                 if (filterContext.HttpContext.Session["user_Name"].ToString() == "Guest")
     75                 {
     76                     filterContext.Controller.ViewData["Title"] = "请登录";
     77                     filterContext.Controller.ViewData["Description"] = "您还没有登录,请登录!";
     78                     //filterContext.RequestContext.HttpContext.Response.Redirect("~/Account/LogOn?ReturnUrl=" + returnUrl);
     79                 }
     80                 else
     81                 {
     82                     filterContext.Controller.ViewData["Title"] = "权限问题";
     83                     filterContext.Controller.ViewData["Description"] = "对不起,你无权访问此页面,请联系管理员!";
     84                 }
     85 
     86                 filterContext.Result = new ViewResult()
     87                 {
     88                     ViewName = "Error",
     89                     ViewData = filterContext.Controller.ViewData,
     90                 };
     91             }
     92 
     93         }
     94 
     95         /// <SUMMARY> 
     96         /// 判断是否允许访问 
     97         /// </SUMMARY> 
     98         /// <SPAN name="user"> </SPAN>用户 
     99         /// <SPAN name="controller"> </SPAN>控制器 
    100         /// <SPAN name="action"> </SPAN>action 
    101         /// <RETURNS>是否允许访问</RETURNS> 
    102         public bool IsAllowed(string controller, string action, List<string> user_Permissions)
    103         {
    104             string permission = controller + "_" + action;
    105 
    106             //如果是登陆,默认通过
    107             if (permission == "Account_LogOn" || permission == "Account_Logon" || permission == "Account_LogOff" || permission == "Account_Register" || permission == "User_CheckUserName")
    108             {
    109                 return true;
    110             }
    111 
    112             if (user_Permissions.Contains(permission))
    113             {
    114                 return true;
    115             }
    116             // 默认禁止访问 
    117             return false;
    118         }
    119     }
    120 }

     2.SetUpUser函数,在用户登录验证通过之后调用,作用是将用户名和用户权限列表保存于session之中

    View Code
            public void SetUpUser(string userName)
            {
                string userTotalPermissions = string.Empty;
                List<string> userTotalPermissionsList = new List<string>();
                List<string> userRoles = this.GetUserRoles(userName);
                foreach (var role in userRoles)
                {
                    List<PermissionItem> permissionList = _IPermissionRepository.CurrentRolePermissions(rolePermissionXml, role);
                    if (permissionList != null)
                    {
                        foreach (var per in permissionList)
                        {
                            string permissionText = per.Controller + "_" + per.Action;
                            userTotalPermissionsList.Add(permissionText);
                        }
                    }
                }
                List<string> userPermissionsList = userTotalPermissionsList.Distinct().ToList();
                foreach (var per in userPermissionsList)
                {
                    userTotalPermissions = userTotalPermissions + "," + per;
                }
                Session["user_Name"] = userName;
                Session["user_Permissions"] = userTotalPermissions.ToString();
            }

    具体使用

    只需要在 BaseController 顶部添加一个 [UserAuthorize]

     -------------------------------------------------------------------

    测试界面

    纯属给大家看下结果,呵呵,没有权限被拒绝

     
     
    管理某个角色的权限:
     
     
     
    管理用户的角色
     
     
     

    后记

    本方案较为简单,适合小项目用哈。当前用户的权限列表存储于session中,再次判断权限时候无需再次读取数据库。

    还有很多问题和不足之处,欢迎大家指正。

  • 相关阅读:
    数据分析人员常犯的五大错误以及预防方法
    SAS中的Order By - Proc Sort
    SAS中的Order By - Proc Sort
    安全数据分析理念的变化
    安全数据分析理念的变化
    spss如何选择需要的变量?
    更改VS2010的[默认开发语言]
    POJ 1273 Drainage Ditches (网络最大流)
    HLS图像处理系列——肤色检測
    并发问题:大数据量的訪问
  • 原文地址:https://www.cnblogs.com/qingzhou/p/2773204.html
Copyright © 2020-2023  润新知