zoukankan      html  css  js  c++  java
  • 权限设计

     

     

           本文主要描述一个通用的权限系统实现思路与过程。也是对此次制作权限管理模块的总结。

           制作此系统的初衷是为了让这个权限系统得以“通用”。就是生产一个web系统通过调用这个权限系统(生成的dll文件),

    就可以实现权限管理。这个权限系统会管理已生产系统的所有用户,菜单,操作项,角色分配,权限分配,日志等内容。

      实现此功能从正常访问和非法访问两个方面入手。正常访问即用户登录系统后只能看到或操作自己拥有的菜单;非法访问即

    通过拼写url等途径访问系统的某个功能;所以程序除了实现用户登录后获取用户拥有的菜单权限,更要挡住用户的非法请求。两

    者缺一不可。

    一.概念

         实现这个功能主要利用RBAC权限设计模型,英文(Role-Based Access Control)译为基于角色的权限管理又叫基于角色的

    访问控制。

    二.数据库设计

     1.系统表:因为要达到"通用",所以这个表会记录各个系统。其他用户、菜单、操作、权限表每条记录都会对应系统代码。

     

     字段说明:Code      —> 系统标识代码

                      SysName  —> 系统名称

    2.菜单表:记录菜单。每个功能当成一个菜单,菜单有url属性,用户通过点击菜单来访问对应功能;

     

     字段说明:ID                  —> 主键,自增标识

                      MenuName     —> 菜单名称

            PageUrl                —> 菜单对应url

            PId                   —> 菜单父级Id

               Lv        —> 菜单等级,分一级菜单和二级菜单

                      ControllerAction  —> 菜单唯一标识,用来做权限控制

                      SystemCode    —> 系统标识代码

    3.操作表:此表主要是为了判断用户是否有来操作某个具体功能,如常用的【删除】功能等操作都放在这个表里;

     

     字段说明:ID                —> 主键,自增标识

                      OprateName   —> 操作名称

               OperateCode     —> 操作标识代码

                      SystemCode       —> 系统标识代码

    4.用户表:记录所有系统的使用用户。记录用户账号、密码等信息;

     

     字段说明:ID            —> 主键,自增标识

                      UserName   —> 用户登录名称

            UserPwd         —> 用户登录密码

                      SystemCode   —> 系统标识代码

    5.角色表:这是RBAC设计不可缺少的,记录角色信息,不同级别的角色拥有不同的权限。给用户分配角色也用到它;

     

     字段说明:ID             —> 主键,自增标识

                      RoleName    —> 角色名称

                      SystemCode   —> 系统标识代码

    6.权限表:存放用户的权限信息。在这个系统里我的设计是每个菜单,每个操作都对应一个权限记录。所以有一个字段[ActionType]

    来区分是菜单还是操作;

     

     字段说明:ID             —> 主键,自增标识

                      PowerName —> 权限名称

            ActionId          —> 菜单或操作ID

            ActionType      —> 区分是菜单或操作

                      SystemCode    —> 系统标识代码

    7.用户对应角色表:这个表负责关联用户和角色的关系。由于初次使用RBAC模型,又为了快速投入使用,因此在这次使用中没有

    考虑一对多的角色。所以在这个系统里用户和角色都是一对一的关系,每个用户对应一个角色;

     

     字段说明:ID             —> 主键,自增标识

                      UserId           —> 用户ID

            RoleId              —> 角色ID

                      SystemCode    —> 系统标识代码

    8.角色对应权限表:这个表负责管理角色和权限的关系。角色和权限属于一对多的关系,每个角色对应多个权限;

     

     字段说明:ID             —> 主键,自增标识

                      RoleId           —> 角色ID

            PowerId           —> 权限ID

                      SystemCode    —> 系统标识代码

    9.日志表:这个应该容易理解,日志表记录用户操作系统的痕迹,像用户信息、访问url、时间等。

     字段说明:ID             —> 主键,自增标识

                      UserId           —> 操作名称

            VisitUrl            —> 操作标识代码

                      Remark           —> 系统标识代码

                      CreateTime     —> 创建时间

                      SystemCode   —> 系统标识代码

    三.程序设计

          上面说了数据库的构造,接下来讲一下此次程序的设计方案。开篇已经提过为了通用此项目最终生成dll文件以便其他系统调用,

    当然你也可以做成webservice,还能满足跨平台。

           这个系统不与任何业务系统公用数据访问层和业务逻辑层。即使两者使用一个相同的数据库,这个系统还是拥有独立的数据访

    问层和业务逻辑层,当然这个情况只限于一个实现权限管理的“权限后台”。

           在此我用了三层,添加了一个接口Service。其他系统只能访问这个接口调用自己需要的方法。这样做对于系统本身有利于避免

    方法被任意调用,功能实现途径不一。对使用者也简洁明了。为了达到这个目的可以用关键字internal修饰数据访问层和业务逻辑层

    的类。程序结构如下图:

     

      继续说说这个接口提供了哪些方法和属性吧。

    1.当前登陆用户:在系统中不少地方要用到它,比如展示登陆用户的账号,角色等,存放登录用户可以使用Session,也可使用Redis;

    2.登录/退出方法;

    2.登陆用户有权限访问的菜单集合:提供使用用户正常访问的菜单,例如树形菜单等;

    3.子菜单集合:方法2也可实现,这个只不过多一个服务而已;

    4.判断操作权限的方法:数据库中有一个操作表,通过操作代码去权限表里查询。判断登陆用户是否拥有某一个操作的权限,例如

    “删除”功能;

    5.日志集合:满足各个系统查看日志的需要。

    四.权限和日志

      这里的权限是为了挡住非正常途径的访问。实现思路是通过用户访问的url跟用户可以访问的菜单属性【ControllerAction】一一

    对比。为了便于理解,在此用开发实例说明一下:

           我做业务系统时UI框架用的是MVC4.0,他很好的支持Filter。因此在权限系统三层的基础上加了一个Filter文件夹,创建PowerAttribute

    类,提供验证登录和验证权限两个类。

    复制代码
        [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
        public class LoginAttribute : ActionFilterAttribute
        {
            /// <summary> 登录验证 </summary>
            /// <param name="filterContext"></param>
            public override void OnActionExecuting(ActionExecutingContext filterContext)
            {
                var loginUser = UserService.LoginUser;
                base.OnActionExecuting(filterContext);
                if (loginUser.ID <= 0)
                {
                    filterContext.Result = new RedirectResult("/home/login");
                    filterContext.Result.ExecuteResult(filterContext);
                }
            }
        }
    复制代码
    复制代码
        [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
        public class PowerAttribute : LoginAttribute
        {
            /// <summary> 访问权限验证 </summary>
            /// <param name="filterContext"></param>
            public override void OnActionExecuting(ActionExecutingContext filterContext)
            {
                LoginAttribute loginAttribute = new LoginAttribute();
                loginAttribute.OnActionExecuting(filterContext);
    
                var routeAction = HttpContext.Current.Request.RequestContext.RouteData.Values["Controller"] + "." + 
    HttpContext.Current.Request.RequestContext.RouteData.Values["Action"]; List<Menu> userOwnMenuList = MenuService.GetUserOwnMenuList().ResultModel as List<Menu> ?? new List<Menu>(); var isHavepermission = userOwnMenuList.FirstOrDefault(m => m.ControllerAction.ToLower() == routeAction.ToLower()) != null; if (!isHavepermission) { HttpContext.Current.Response.Write("您没有权限访问"); HttpContext.Current.Response.End(); } } }
    复制代码

      访问【用户列表】时,只需在对应的Action上添加特性Power即可。

        // GET: /User/List
        // 用户列表页
        [Power]
        [Log(Desc = "查看用户列表")]
        public ActionResult List(string code = "", int page = 1)

      出处:http://www.cnblogs.com/paulhe/p/4028389.html

  • 相关阅读:
    dfs模板(真心不会深搜)
    背包九讲文档
    POJ3414—Pots(bfs加回溯)
    统计元音
    前m大的数(哈希入门)&&sort
    数据结构实验:哈希表
    More is better
    畅通工程&&How Many Tables
    OpenCV学习:Mat结构中的数据共享机制
    VC++ :实现简单的文件拖放(Drag and Drop)功能
  • 原文地址:https://www.cnblogs.com/Justsoso-WYH/p/10030223.html
Copyright © 2011-2022 走看看