二进制实现权限的分配管理
大部分系统都有权限系统。一般来说,它能管控人员对某个否页面的访问;对某些字段、控件可见或者不可见。对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
有丰富的权限管理系统设计经验
有现成可用的类似权限管理模块最好