设计用户权限杂谈

来源:互联网 发布:hifi raver动作数据 编辑:程序博客网 时间:2024/06/15 07:54

(1)

  但凡涉及多用户不同权限的网络或者单机程序,都会有权限管理的问题,比较突出的是MIS系统。    
   
  下面我要说的是MIS系统权限管理的数据库设计及实现,当然,这些思路也可以推广开来应用,比如说在BBS中用来管理不同级别的用户权限。    
   
  权限设计通常包括数据库设计、应用程序接口(API)设计、程序实现三个部分。    
   
  这三个部分相互依存,密不可分,要实现完善的权限管理体系,必须考虑到每一个环节可行性与复杂程度甚至执行效率。    
   
  我们将权限分类,首先是针对数据存取的权限,通常有录入、浏览、修改、删除四种,其次是功能,它可以包括例如统计等所有非直接数据存取操作,另外,我们还可能对一些关键数据表某些字段的存取进行限制。除此,我想不出还有另外种类的权限类别。    
   
  完善的权限设计应该具有充分的可扩展性,也就是说,系统增加了新的其它功能不应该对整个权限管理体系带来较大的变化,要达到这个目的,首先是数据库设计合理,其次是应用程序接口规范。    
   
  我们先讨论数据库设计。通常我们使用关系数据库,这里不讨论基于Lotus产品的权限管理。    
   
  权限表及相关内容大体可以用六个表来描述,如下:    
  1   角色(即用户组)表:包括三个字段,ID,角色名,对该角色的描述;    
  2   用户表:包括三个或以上字段,ID,用户名,对该用户的描述,其它(如地址、电话等信息);    
  3   角色-用户对应表:该表记录用户与角色之间的对应关系,一个用户可以隶属于多个角色,一个角色组也可拥有多个用户。包括三个字段,ID,角色ID,用户ID;    
  4   限制内容列表:该表记录所有需要加以权限区分限制的数据表、功能和字段等内容及其描述,包括三个字段,ID,名称,描述;    
  5   权限列表:该表记录所有要加以控制的权限,如录入、修改、删除、执行等,也包括三个字段,ID,名称,描述;    
  6  权限-角色-用户对应表:一般情况下,我们对角色/用户所拥有的权限做如下规定,角色拥有明令允许的权限,其它一律禁止,用户继承所属角色的全部权限,在此范围内的权限除明令禁止外全部允许,范围外权限除明令允许外全部禁止。该表的设计是权限管理的重点,设计的思路也很多,可以说各有千秋,不能生搬硬套说某种方法好。对此,我的看法是就个人情况,找自己觉得合适能解决问题的用。    
   
  先说第一种也是最容易理解的方法,设计五个字段:ID,限制内容ID,权限ID,角色/用户类型(布尔型字段,用来描述一条记录记录的是角色权限还是用户权限),角色/用户ID,权限类型(布尔型字段,用来描述一条记录表示允许还是禁止)    
   
  好了,有这六个表,根据表六,我们就可以知道某个角色/用户到底拥有/禁止某种权限。    
   
 或者说,这么设计已经足够了,我们完全实现了所需要的功能:可以对角色和用户分别进行权限定制,也具有相当的可扩展性,比如说增加了新功能,我们只需要添加一条或者几条记录就可以,同时应用程序接口也无须改动,具有相当的可行性。但是,在程序实现的过程中,我们发现,使用这种方法并不是十分科学,例如浏览某个用户所拥有的权限时,需要对数据库进行多次(甚至是递归)查询,极不方便。于是我们需要想其它的办法。使用过Unix系统的人们都知道,Unix文件系统将对文件的操作权限分为三种:读、写和执行,分别用1、2、4三个代码标识,对用户同时具有读写权限的文件被记录为3,即1+2。我们也可以用类似的办法来解决这个问题。初步的想法是修改权限列表,加入一个字段:标识码,例如,我们可以将录入权限标识为1,浏览权限标识为2,修改权限标识为4,删除权限标识为8,执行权限标识为16,这样,我们通过权限累加的办法就可以轻易的将原本要分为几条记录描述的权限放在一起了,例如,假定某用户ID为1,库存表对应的限制内容ID为2,同时规定角色类型为0、用户类型为1,我们就可以将该用户具有录入、浏览、修改、删除库存表的权限描述为:2,15,1,1。   
   
 确实很简单,不是吗?甚至还有更过激的办法,将限制内容列表也加上一列,定义好标识码,这样,我们甚至可以用简单的一条记录描述某个用户具有的对全部内容所具有的全部权限了。当然,这样做的前提是限制内容数量比较小,不然,呵呵,2的n次方递增起来可是数量惊人,不容易解析的。    
   
 从表面上看,上述方法足以达到实现功能、简化数据库设计及实现的复杂度这个目的,但这样做有个弊端,我们所涉及的权限列表不是相互独立而是互相依赖的,比如说修改权限,其实是包含浏览权限的,例如,我们可能只是简单的设置用户对库存表存取的权限值为录入+修改+删除(1+4+8=13),但事实上,该用户具有(1+2+4+8=15)的权限,也就是说,在这种方案中,13=15。于是当我们调用API询问某用户是否具有浏览权限时,就必须判断该用户是否具有对该数据表的修改权限,因此,如果不能在程序中固化权限之间的包含关系,就不能利用应用程序接口简单的做出判断。但这与我们的目的“充分的可扩展性”矛盾。    
   
 这个问题如何解决?我想到了另外一种设置标识码的方法,那就是利用素数。我们不妨将录入、浏览、修改、删除、执行的基本标志码定为2,3,5,7,11,当遇到权限互相包含的时候,我们将它的标识码设定为两个(或多个)基本标志码的乘积,例如,可以将“修改”功能的标志码定为3*5=15,然后将所有的权限相乘,就得到了我们需要的最终权限标识值。这样,我们在询问用户是否具有某项权限的时候,只需要将最终的值分解成质因子,例如,我们可以定义一个用户具有录入+修改+删除库存表的权限为   2*15*7=2*3*5*7,即表示,该用户具有了对库存表录入+浏览+修改+删除权限。

(2)

 1.可以对用户授权也可以对用户所属组授权,而用户所属组可以有多个(用户信息中有所属组列表属性),比如“董事会”组中某成员完全也可以是“部门经理”组的成员,组与个人用户一样在用户表中可以创建,不同的是没有密码和真实姓名等信息(没有信箱等基础设施,只是身份转定义桥);  
  2.所有文档属于栏目,栏目管理员对栏目具有最高权限,所有栏目权限分为:模板定义、模板审批、内容创建、内容审批;  
 3.浏览权限由文档的发布对象(邮件收件人或者栏目,发布到栏目的必须有该栏目发布权限,有该栏目发布权限的未必有浏览权限,比如“归档”栏目可能只有档案管理员可以看)定义,某绝密文档可能一个销售员就能看但财务经理不能看,如果对每类文档去定义,累死也不成的。  
  这样,当发布规章制度等一类完全公开的文档时,所有人都可以看,而内部公文则只有邮件收件人可以看并自动归档。  
  邮件可以有禁止转发属性,此类邮件的文本是防拷贝的。

 

(3)  
 在现实中,权限控制包括一个用户所担任岗位、角色,岗位与角色的有点区别。岗位是专门负责某方面的一个角色,如:一个局下面有好几个分局,相应的设立了多个分局长,这个“分局长”就是角色,岗位就是:××局分局长。这样,某个岗位的人看到的数据就与别的岗位的应该有所区别。
  如果涉及到对记录行的管理呢?如何做?  
  比如有一个仓库管理软件,产品有好多种,A可能管理办公用品的,B可能管理电子产品的,那么A不能处理和查看B的记录,这种权限如何实现?”  
 也就是说,A与B的岗位责任区不一样。这里就新提出一个责任区的概念。责任区与人无关,只与岗位有关系。所以:岗位=角色+责任区。而角色权限控制是对该角色能对哪些程序业务模块进行操作的控制。只要对一个用户赋于特定的岗位(当然是可以多个岗位的),就可以控制该用户的系统功能使用权限、数据查询范围。 
   
 这样新的需要也就出来了,不同岗位的人使用同一模块时,所拥有的权限是不一样的。(这里先假设该模块有如下功能:增加删除修改提交审批查询)这也是上面大家所说的对象权限。根据我这里所实现的整个权限体系,可以自由配置某个角色对某模块里某个表的对象权限;可以自由配置该模块哪个字段是否只读。这样,在一个流程里,只需做一个模块,就可以让不同的岗位的人进行相应的数据流操作:开单人只能进行开单、提交,审核人只能进行审核、提交、退单,不能删除修改。其它的流程控制就不属于这里所讨论范围了。(具体如何实现请不要问我了,我现在难得上一次CSDN的)  
   
  这样,权限控制能做到对象级、数据级、字段级。所有的控制全部可以由系统管理员进行配置,程序开发时不必针对不同的权限要求来另外开发相应的模块。

(4)

用户当然是可以属于多个角色的,但是要求每次登录只用一个角色不行吗。你可以按部门划分开,你想管理财务,就登录财务的部门;你想去管销售,那再登录销售的部门;如果想同时做两件事,恩,要么麻烦点,换角色,要么来个角色继承(临时想的,没想怎么实现之)  
   
  一个用户在系统中有几个账号,要做什么事,用相应的账号登录就可以了。只要能用户接受,就可以用这种方法实现。  
  跟这个类似的一个办法,不需要添加几个账号。就和网易通行证一样,进入系统后可以选择各种不同的服务(功能)。这个比较容易在B/S系统中实现,C/S模式的可以参考网易泡泡。  
   
  关于角色继承,依我看一般的系统中没必要弄得这么复杂,可以使用别的替代解决方法,比如提供增加角色的功能,然后定义角色的权限而不是设置这个角色属于其它角色组。

 

 

原创粉丝点击