追梦人.Net学习日记

  ASP.NET学习,需要我们去实践中模索,记录一些平时学习中的点点滴滴.....

   :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

大概有这几种模式:
用户+组+角色+权限
用户+组+权限
用户+角色+权限
用户+权限

最近看了别人的设计方法,大多以“整数”来表示权限值,如添加、浏览、删除和修改,分别用1、2、4、8这几个整数来代替,不过,各人的做法有所不同,举例如下:

1. 用2的n次幂组成权限值的集合,如1、2、4、8、16...,某用户的权限值为其子集中的整数之和,如 7=1+2+4,5=1+4。如果要从数据库检索包含某几种权限的用户,则先把这几种权限值相加,假设和为k,然后select * from table where 1 and 用户权限值 = 'k';如果要判断某用户有哪些权限,则取出其权限值k,分别用k&1,K&2,K&4,k&16...,如果为真,则 表示有值等于“&”右边整数的权限,例如,如果k&4为真,则此用户有权限表中值等于4的权限;

2.用质数2、3、 5、7、11...组成权限集合,某用户的权限为其子集中各整数的乘积,如 210 = 2*3*5*7,我觉得这种方法很有趣,难点在于如何分解质因数;但我有些不认同原作者的提法,他认为权限之间可能存在包含关系,如某用户有删除权限,则 其一定有浏览权限,要不然就没法删除,事实确实是这样,不过我认为这样太复杂了,容易出错,我觉得权限最好是“原子”的,互不干扰,也就是说某用户有删除 权限而没浏览权限则其无法进行删除操作,因为他看不到东西,解决这个矛盾的关键是在给用户赋权时,把浏览权限也赋给他;

3.不用整 数,而是用“向量表”方法(也许我说的不一定对),把所有可能的权限按一定的顺序排列,如添加、浏览、修改、删除...,用户的权限值为固定100位长度 的字符串,如100010100001....01,从左起每一位对应一种操作权限,如果有这种权限,则此位的值为1,反之,则为0,作者之所以把用户权 限值固定为100位,我想是考虑到升级问题,但我认为这还不够科学,我认为用户的权限值长度应小于权限个数,举例如下:
权限排列表:添加、浏览、修改、删除,用户A有添加和浏览的的权限,则其权限值为11,用户B有浏览和修改的权限则其权限值为011,用户C有浏览和删除的权限则其权限值为0101,这样设计的好处为:当权限表中增加别的权限时,不会影响用户表或角色表;

应用软件系统权限问题的另类解决方法

权限管理确是个很麻烦的问题
例如,一个系统中,有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结构原来是取消了

posted on 2006-11-07 15:05  ZmStudio.CN  阅读(449)  评论(0编辑  收藏  举报