原文地址:http://www.chenjiliang.com/Article/View.aspx?ArticleID=752
应用软件系统权限问题的另类解决方法
权限管理确是个很麻烦的问题
例如,一个系统中,有N个模块,每个模块有添加,删除,修改,完全控制,列表等权限
有N个用户,现在的问题是,通常,我们会建立一个数据表来表示权限分配,这个数据表的一般形式是
用户ID 添加 删除 修改 完全控制
3 0 1 1 3
这样一般来说没什么问题,突然有一天,你需要有一种新权限例如叫做运行,这时候,问题就来了,你得更改数据表,添加对应的字段呀,不光如此,
程序中的逻辑也有问题了
当然,也有更聪明的兄弟使用另一种设计方法,就是包含式权限设计,类似WINDOWS系统中,每一种权限,将包含前一种权限,例如
读取是最基本的,运行包含读取,列表包含运行,修改包含列表以此类推,用数字表示就是
读取 1
列表 2
运行 3
修改 4
删除 5
....
以此类推,这样,就将第一种方法的扩展问题解决掉了,当有新的权限时,在应用程序中,为其指定一个新的权值就可以了,在实际判断权限中,例如
,判断有无修改权,就比较用户权限值是不是大于或等于4,就可以了
听起来不错,似乎解决了问题,但是,再想想看,不对,这个设计的确使权限的扩展性强了,可是,也使权限体系的灵活性降低了,为什么呢?假如,有
一个用户,我想给他读取,修改两种权限,而不想给他运行和列表权限,这下怎么办呢?这个设计是等级制的权限,权限具有自高往低的包含,因此,
根本无法实现这种自由组合
难道真的没有办法了吗?
NO!
每一种权限,相当于一种开关,也就是一个BIT,假如我们将这些权限,每一种权限用一位表示,那么,整个权限体系,不过是个BIT序列而已,也就是
说不过是二进制的011010而已,这样一来,就好解决问题了
同样的问题,我们这样假设:
第一位 表示 读取
第二位 表示 运行
第三位 表示 修改
第四位 表示 删除
......
以此类推,假如,我们想给一个用户分配运行和修改权限,其他权限都不给予,于是,他的权限字符串可以表示为:0110,这样,用若干个位的组合,我
们就解决了权限的灵活组合问题(位组合这种解决方案,真是比比皆是,其实,他就是一种数据结构而已,我们叫他UNION?)
另外一方面呢?如何扩展?扩展就更容易了,当添加新的权限时,可以直接在高位加上一位即可
如何判断有无某权限呢?我们可以直接取某位的值,根据其0,一来判断即可
最后,实际上,C/C++/C#中,你可以做得更棒,那就是定义一个枚举类型,例如:
enum rights { read, list, exec, write, delete }
这样的好处是用名字来引用权限,就更好了
判断权限时,可以使用按位与,例如,用户权限为100001
而运行需要的权限是1000
两者按位与的结果是00000000,显然无此权限,用公式表示就是
RN & R=RN,则代表用户有此权限,我的意思是
所需权限&用户权限=所需权限 符合此条件,即表明有权限
写的比较抽象,但是,相信有权限设计经验的朋友一看就明白了
我也是在最近设计一个系统时,被客户的变化逼的不行,后来,受<编程珠玑>一书中第一章关于对100万个电话号码进行排序的文章中受到的启发
BW:C#中的UNION结构原来是取消了-:(