zoukankan      html  css  js  c++  java
  • 二进制实现权限的分配管理

    大部分系统都有权限系统。一般来说,它能管控人员对某个否页面的访问;对某些字段、控件可见或者不可见。对gridview中的数据是否可删除、可添加、可新增等等。大部分人都把权限作为一个子系统独立出来。但是这里我不是想设计一个权限管理系统,网上的设计方案太多了,可以说每个开发人员都有自己的开发权限管理系统的想法和思路。

       在这篇文章中,我先用简单的C#代码模仿一个用户的权限,再使用sql去模拟。这是一种很简单,很直观,很高效的方式去判定用户的权限。

    C#:

       好吧,先从最简单开始,定义一个用户(User)类,如下。

    1 class User 
    2 {
    3     bool CanDelete;
    4     bool CanRead;
    5     bool CanWrite;
    6     bool CanModify;
    7     bool CanCreate;
    8 }

        这里设计5个属性来管控用户的权限。我发现这样虽然很直观,但是不宜扩张。我们将权限独立出来,在看下面代码:

     1     enum PermissionTypes : int 
     2     {
     3         None = 0,
     4         Read = 1,
     5         Write = 2,
     6         Modify = 4,
     7         Delete = 8,
     8         Create = 16,
     9         All = Read | Write | Modify | Delete | Create
    10     }
    11     class User 
    12     {
    13        public PermissionTypes Permissions = PermissionTypes.None;
    14     }

        我们先试用一下,你就能感觉到神奇之处:

     1 //创建一个用户
     2 User admin = new User();
     3 admin.Permissions = PermissionTypes.Read
     4     | PermissionTypes.Write
     5     | PermissionTypes.Delete;
     6 
     7 //验证权限
     8 bool canRead = ((PermissionTypes.Read & admin.Permissions) == PermissionTypes.Read);
     9 bool canWrite = ((PermissionTypes.Write & admin.Permissions) == PermissionTypes.Write);
    10 bool canCreate = ((PermissionTypes.Create & admin.Permissions) == PermissionTypes.Create);
    11 
    12 //查看结果
    13 Console.WriteLine(canRead); //true
    14 Console.WriteLine(canWrite); //true
    15 Console.WriteLine(canCreate); //false
    16 

        利用了'|'和'&'两个操作。但是这样看起来很是很别捏,初始化权限和验证权限用了一长串'|'和'&'运算的代码。很不直观。我在System.Enum中扩展一些方法供你调用,代码如下。

     

     1   //是否存在权限
     2         public static bool Has<T>(this System.Enum type, T value)
     3         {
     4             try
     5             {
     6                 return (((int)(object)type & (int)(object)value) == (int)(object)value);
     7             }
     8             catch
     9             {
    10                 return false;
    11             }
    12         }
    13         //判断权限
    14         public static bool Is<T>(this System.Enum type, T value)
    15         {
    16             try
    17             {
    18                 return (int)(object)type == (int)(object)value;
    19             }
    20             catch
    21             {
    22                 return false;
    23             }
    24         }
    25         //添加权限
    26         public static T Add<T>(this System.Enum type, T value)
    27         {
    28             try
    29             {
    30                 return (T)(object)(((int)(object)type | (int)(object)value));
    31             }
    32             catch (Exception ex)
    33             {
    34                 throw new ArgumentException(
    35                     string.Format(
    36                         "不能添加类型 '{0}'",
    37                         typeof(T).Name
    38                         ), ex);
    39             }
    40         }
    41 
    42         //移除权限
    43         public static T Remove<T>(this System.Enum type, T value)
    44         {
    45             try
    46             {
    47                 return (T)(object)(((int)(object)type & ~(int)(object)value));
    48             }
    49             catch (Exception ex)
    50             {
    51                 throw new ArgumentException(
    52                     string.Format(
    53                         "不能移除类型 '{0}'",
    54                         typeof(T).Name
    55                         ), ex);
    56             }
    57         }

     

    使用一下:

     1            //创建一个用户
     2             User admin = new User();
     3             PermissionTypes permissions = new PermissionTypes();
     4             admin.Permissions = permissions;
     5             //添加权限
     6             admin.Permissions = admin.Permissions.Add(PermissionTypes.Create);
     7             admin.Permissions = admin.Permissions.Add(PermissionTypes.Read);
     8             admin.Permissions = admin.Permissions.Add(PermissionTypes.Write);
     9            //判断权限
    10             bool canRead = admin.Permissions.Has(PermissionTypes.Read); //true
    11             bool canWrite = admin.Permissions.Has(PermissionTypes.Write); //true
    12             bool canDelete = admin.Permissions.Has(PermissionTypes.Delete); //false
    13             bool canCreate = admin.Permissions.Has(PermissionTypes.Create); //true
    14 
    15             Console.WriteLine(canRead); //true
    16             Console.WriteLine(canWrite); //true
    17             Console.WriteLine(canDelete); //false
    18             Console.WriteLine(canCreate); //true
    19             Console.Read();

    SQL:

        大部分权限管理都是数据库的操作,好依照上面的思路,我在sqlserver里面模拟一下以上的操作,在sql中与或运算是很高效的。先设计两张表User和Permission。

     

     

     

    1、获取有Read权限的所有用户:

    1 select * from [User] where PermissionTypes&1 =1 

    Result:

     

    2、获取有Delete权限的所有用户:

    1 select * from [User] where PermissionTypes&8 =8

    Result:

     

    3、判断麒麟是否有有Delete权限

    1 if  exists (select * from [User] where Name='qilin' and  PermissionTypes&8 =8)
    2     print 'true'
    3 else
    4     print 'flase'

    Result: flase

    【项目内容描述】

    ASP.NET 权限管理系统设计具体需求

     

    1、 应包括以下模块:功能模块管理、角色管理、用户管理、角色授权、用户授权

             功能模块管理:管理系统中可用模块的地址、功能在HTML页面的显示功能名和树状结构(即上下级关系)等,已经增加的项目不可实际删除,可采用删除标记方式来记录已经被删除的功能

             角色管理:为方便用户授权而使用的一组权限集合体,可选择一个或多个用户(如多个一次同时授权不能实现,也可单个独立授权)进入角色权限管理模块

             用户管理:管理参与系统操作的用户信息,每个用户都必须是和其管理业务相关的部门下员工,提供用户管理到用户授权的关系链接

             角色授权:系统中存在的角色进行授权操作,一个角色可授权多个功能模块,一个功能模块也可授权给多个角色,系统提供角色选择的查询界面,可选择一个或多个用户(如多个一次同时授权不能实现,也可单个独立授权)同时进行可操作功能模块的授权管理,每个功能模块上又有多个操作按钮,也需要进行权限控制

             用户授权:对系统中存在的用户进行授权操作,一个用户可授多个角色权限,也可授多个直接的功能模块权限,每个功能模块上又有多个操作按钮,也需要进行权限控制

             (注:用一个字段记录此按钮权限,对每种权限使用一位数据的方式来判断是否具有此功能,如:审核——第1位、新增——第2位、修改——第3位、删除——第4位,则1011表示,此用户或角色具有:查询、修改、删除权限,但不具有新增权限)

             按钮功能采用规定按钮ID和名称的形式进行控制(按钮名称为:新增:btn_Add,修改:btn_Edit,删除btn_Delete)

             用户权限能够控制到数据级,即:上级部门的用户能够观看下级用户的数据,而下级用户不能观看上级用户生成的数据。注:此数据由数据的组织机构编码来判断。

             用户进行权限管理时,除ADMIN用户能增加顶级用户外,其他用户只有增加比本用户权限更低级的用户,系统只有一个ADMIN用户,且不可维护。ADMIN用户不属于任何一个部门(即此用户不能参与业务操作)

    2、 用户登录后,系统根据用户登录权限,自动将其能够操作的功能树展现,但只展现其能够使用的功能权限树,

    3、 菜单树分为2层:分布在上方的为一级菜单树,分布在左方的为二级以下菜单树(含二级)且能够与一级菜单树产生JS连动效果

    4、 能够控制界面上按钮(查询、新增、修改、删除)等多种操作单独设置

    5、 能够根据数据库中的模块结构生成相应的功能模块树(型结构)

    6、 授权时,应考虑菜单的父子关系,如:授予子节点A1权限时,其父节点A的访问权限必须获得授权

    7、授权界面显示最好能够将功能模块的父子关系显示出来

    8、 符合数据库设计要求:

    用户信息表可自主创建,但必须包括后面用户信息表(POPEDOM_USER)中定义的几个字段

    其中:

    EMP_ID来自员工基本信息表EMP_ID

    LOGIN_ID是指用户用来登录系统使用的ID

    LOGIN_PASSWORD

    表中创建人ID和创建时间为此数据第一次创建时的操作员及时间(创建人填写的为EMP_ID而不是登录ID)

    表中修改人ID和修改时间为本次修改时的操作员及时间,若为第一次,此项输入与创建人ID和创建时间相同,

    其他的表只是参考实现,可以进行表名及模块名的变更,另:用户与功能模块对应表未创建,可参照用户与角色表进行创建。

     

     

    9、 数据库参考实现:

    用户信息表 POPEDOM_USER

    英文字段名       中文字段名       数据类型及长度   是否可为空        备注

    EMP_ID   员工信息表ID     CHAR(24)         PK

    LOGIN_ID 登录ID  VARCHAR(50)      是      

    LOGIN_PASSWORD   登录帐户密码     VARCHAR(50)      是      

     

    系统模块基本表 POPEDOM_MODULE

    英文字段名       中文字段名       数据类型及长度   是否可为空        备注

    MODULE_ID        系统模块基本表ID CHAR(24)         PK

    MODULE_NAME      模块名称 VARCHAR(50)              

    MODULE_PATH      模块路径 VARCHAR(50)              

    SUPMODULE_ID     上级模块ID       CHAR(24)         FK

    DESCR    描述     VARCHAR(200)     是      

    CREATE_EMPID     创建人ID CHAR(24)         FK

    CREATE_DATE      创建时间 DATETIME        

    UPDATE_EMPID     修改人ID CHAR(24)         FK

    UPDATE_DATE      修改时间 DATETIME        

    DEPT_CODE        组织机构编号     Varchar(32)               FK

    ISDEL    删除标示 CHAR(1)          0否1是

     

    角色基本表 POPEDOM_ROLE

    英文字段名       中文字段名       数据类型及长度   是否可为空        备注

    ROLE_ID  角色基本表ID     CHAR(24)         PK

    ROLE_NAME        角色名称 VARCHAR(50)              

    DESCR    描述     VARCHAR(200)     是      

    CREATE_EMPID     创建人ID CHAR(24)         FK

    CREATE_DATE      创建时间 DATETIME        

    UPDATE_EMPID     修改人ID CHAR(24)         FK

    UPDATE_DATE      修改时间 DATETIME        

    DEPT_CODE        组织机构编号     Varchar(32)               FK

    ISDEL    删除标示 CHAR(1)          0否1是

     

     

    角色控制模块的权限表 POPEDOM_ROLECORR_MODULE

    英文字段名       中文字段名       数据类型及长度   是否可为空        备注

    ROLECORR_MODULE_ID        角色控制模块的权限表ID    CHAR(24)          PK

    ROLE_ID  角色基本表ID     CHAR(24)         PK

    MODULE_ID        系统模块基本表ID CHAR(24)         PK

    RIGHT_SIGN       权限标示 CHAR(8)          权限标示(1审核2添加3修改4删除) 0000

    DESCR    描述     VARCHAR(200)     是      

    CREATE_EMPID     创建人ID CHAR(24)         FK

    CREATE_DATE      创建时间 DATETIME        

    UPDATE_EMPID     修改人ID CHAR(24)         FK

    UPDATE_DATE      修改时间 DATETIME        

    DEPT_CODE        组织机构编号     Varchar(32)               FK

    ISDEL    删除标示 CHAR(1)          0否1是

     

    用户与角色对应表 POPEDOM_EMPCORR_ROLE

    英文字段名       中文字段名       数据类型及长度   是否可为空        备注

    EMPCORR_ROLE_ID  用户与角色对应表ID        CHAR(24)         PK

    EMP_ID   用户ID  CHAR(24)         FK

    ROLE_ID  角色基本表ID     CHAR(24)         FK

    DESCR    描述     VARCHAR(200)     是      

    CREATE_EMPID     创建人ID CHAR(24)         FK

    CREATE_DATE      创建时间 DATETIME        

    UPDATE_EMPID     修改人ID CHAR(24)         FK

    UPDATE_DATE      修改时间 DATETIME        

    DEPT_CODE        组织机构编号     Varchar(32)               FK

    ISDEL    删除标示 CHAR(1)          0否1是

     

    【接包方必备的条件】

    精通C#与ASP.NET

    有丰富的权限管理系统设计经验

    有现成可用的类似权限管理模块最好

  • 相关阅读:
    用PHPMailer在本地win环境,可以接收到邮件和附件,但在linux环境只能接收邮件信息接不到附件,是我的路
    linux 下 用phpmailer类smtp发送邮件始终不成功,提示:ERROR: Failed to co
    linux 下 用phpmailer类smtp发送邮件始终不成功,提示:ERROR: Failed to co
    phpmailer的SMTP ERROR: Failed to connect to server: 10
    SDK是什么?什么是SDK
    查看php的配置文件Php.ini的位置
    紧急求助!配置SMTP插件出错,SMTP connect() failed
    PHP move_uploaded_file() 函数
    HTML 5 video 视频标签全属性详解
    RAID级别与规范
  • 原文地址:https://www.cnblogs.com/lyunyu/p/3681228.html
Copyright © 2011-2022 走看看