您的位置:首页 > 其它

项目权限管理分析

2013-05-03 15:27 204 查看
需求

OA(Office Automation)系统包含很多模块,它要求针对不同用户要有不同的操作或者说是界面展示,这样我们就不得不考虑使用一种能够控制不同用户访问不同模块甚至是一个模块中不同功能点的管理方式,即我们将要介绍的权限管理。我们这个OA系统里的权限管理控制用户访问到CRUD(增删改查)的操作级别,要求能够通过角色对用户进行统一的授权,而且能再某些特殊的情况下,能够单独的对用户进行授权,所以我们这个OA系统的权限管理是比较强大的,当然实现上就相对会复杂一些。

分析

Rose建模分析(最终模型)



设计

在用户与角色的关系中,这个系统采用了以用户为主来进行设计,这样似乎更符合客户的使用习惯,即“将多个角色授予某个用户(让用户拥有多个角色)”。
模块的授权以针对角色为主,即大部分的情况下,针对角色来分配模块的权限

一旦根据角色划分好权限之后,就可以进行用户的创建工作,同时可以给用户分配角色(可以为多个),用户将拥有其所属角色的所有权限(这样就达到了统一控制的目的)

由于一个用户可以拥有多个角色,这样做的目的也是为了给客户提供更大的灵活性,但是也会造成系统无法对角色的授权进行控制,比如:很有可能出现授权有冲突的多个角色被授予同一个用户的情况,比如:角色A对模块A有删除权限,但角色B对模块A的删除权限则被禁止,这时候,如果将角色A和角色B同时授予用户A,则会造成困扰,究竟用户A对模块A的删除权限是允许还是不允许?它应该是以角色A的授权为准,还是应该以角色B的授权为准?其实这个问题我们现实生活中可能很容易就知道该怎么办了,但是系统毕竟是死的,不像人一样能够遇到突发情况随机应变,它需要按照我们编写的程序来执行,所以我们还是需要将各种解决方案编成指令交给计算机来执行。针对这个问题,可以考虑如下解决办法:

第一种解决办法是:如果多个角色之间有授权冲突,则不允许将这些角色同时授予同一个用户,比如,在上述例子中,不允许将角色A和角色B同时授予用户A(这种办法貌似过于强硬,不容易被用户接受)

第二种解决办法是:允许将有授权冲突的角色同时授予同一个用户,但用户在某个时刻只能扮演其中的某个角色。在用户登陆后台管理界面之后,可以通过切换角色,来执行不同的操作!(这种办法虽然顾全大局,但是又过于繁琐,也很难被用户接受)
第三种解决办法是:允许将有授权冲突的角色同时授予同一个用户,对用户的这些角色来说,有优先级的概念,当将角色分配给用户的时候,应该设置它的优先级。同一个角色在不同的用户那里可能具有不同的优先级。当授权有冲突的时候,以优先级更高的角色授权为准。(这种办法符合我们的生活习惯,看来它才是解决问题的最好途径,本系统正是采用了这种办法)
至此,用户与角色之间的设计思路便清晰起来(如上图用户角色关系)。

再来看授权,本系统设计可以把模块的增删改查操作授予某个角色或用户,并设置为允许或禁止此操作。我们考虑使用授权控制列表来存储授权信息。在现有需求下,授权的主要要素是:一个是角色或用户;一个是模块;一个是操作;一个是允许/禁止。这也就是授权控制列表(ACL)的主要要素。
进一步的思考是:操作包括“增删改查”四种操作,针对这每一种操作,需要一个对应的“允许/禁止”标识。最直观和直接的考虑便是:ACL针对每种操作设置一个属性,和一个“允许/禁止”的标识。但是这种设计会造成灵活性的缺失。比如有可能随着需求的变更,添加了其它的操作类型,那时候必须对ACL做必要的更改才能适应需求的变化。为了适应这种可预见的需求,可将操作及其“允许/禁止”标识设计如下:
在ACL中,设计一个int类型的状态位:aclState,在Java中,int类型有32位,用位(bit)来表示操作类型(暂定:第0位表示“增”;第1位表示“删”;第2位表示“改”;第3位表示“查”),位的值(对于“位”来说,只能取值0或1)用来表示“允许/禁止”(0表示禁止,1表示允许)。这样,操作类型及其“允许/禁止”标识便能合二为一,而且提高了灵活性(能支持将来可能会增加的多达32种操作类型),因为对于某个模块而言,针对这个模块的操作能够超过32个的情况,是几乎不会发生的,因此对这种特殊情况可以不予考虑。

客户要求在特殊的情况下,能够直接对用户进行授权。意思是不管其角色的授权如何,始终采取针对用户的授权来作为最终的授权。而且,要求控制到的粒度是模块(即可以针对某个模块设置给某用户单独的授权)。当然,在设置好授权之后,可以在适当的时候再开放给用户使用。因此,这里有一个针对用户的授权是否有效的问题。可采取添加另外一个int类型的状态位(aclTriState)的办法来满足这种需求。这个额外状态位用-1表示针对用户的授权无效;用0表示针对用户的授权有效。之所以使用-1和0来表示无效/有效,是因为-1代表了一个32位全1的int类型值;而0则代表了一个32位全0的int类型值。此设计隐含的意思是:aclTriState的位与aclState的位一致,而且某个位所表示的操作也是一致的,取1表示无效,取0表示有效(用0还是1来表示有效,这个可以随便)。这种设计是为了将来可能扩展的需要。现在的需求是能对模块的授权控制其有效/无效即可,将来有可能需要对模块的操作(增删改查)的授权控制其有效/无效。这种控制粒度更细。如果要控制到更细的粒度,那么,aclTriState可以取更多的状态值,来表示操作级别的有效/无效。
有效/无效的意思是:如果无效,则用户对此模块的授权将受到其所属角色的统一控制;如果有效,则角色对此模块的授权将无法影响到拥有这个角色的用户的授权。

实现

权限管理模块在实现上,有多个用例需要实现:管理模块信息、管理用户信息、管理角色信息、给用户分配角色、给角色授权、给用户授权、获取用户授权列表、判断用户对某个模块的某操作是否有允许授权

其中比较重要的是:授权、获取用户授权列表以及判断用户对某个模块的某操作是否有允许授权

授权:可针对用户或角色授权,在授权界面上,根据系统现有模块,列出授权树,可选择其中的某些模块和某些操作进行授权。因为鉴于授权界面的复杂性,采取DWR来辅助实现授权界面(DWR可以异步完成授权操作)。

获取用户授权列表:在用户登陆系统之后,需要根据用户的授权情况,获得用户的授权列表,并根据用户的授权列表,在后台界面的导航菜单上显示出用户拥有权限的模块,允许用户对这些模块进行操作。
判断用户对某个模块的某操作是否有允许授权:为了控制用户对模块的增删改查操作,需要根据用户的授权情况,决定是否显示“增加”、“删除”、“修改”等按钮或链接。我们采取自定义JSTL函数的方式来控制界面的显示!如:

<!-- login.id表示当前登陆用户,’person’表示模块标识,3代表删除操作 -->
<c:iftest="${my:hasPermission(login.id,'person',3) }">
<a href="#"onclick="del('person.do?method=del&id=${person.id }');">删除</a>
</c:if>

至此OA系统的权限管理基本上就介绍完了,主要的操作及实现方案也说明白了,做完这个系统之后感觉这个方案虽然考虑的比较全面,但是整体的实现还是感觉有点复杂,尤其是授权过程感觉做的太细,条件太多,应该还能简单一些的。剩下的应该是我们自己思考更好的实现更加简单的权限管理方案了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: