AGILEJ的权限控制

在 RBAC的模型中角色将是可继承性的,即如果角色A财务部经理是角色B财务员的父类,则角色A将会拥有角色B的所有权限,那么一个公司/组织的结构则是一个树型结构。在这里我们将会虚拟一个根节点,作为所有角色的祖先。如下图所示。

目前的权限模型(RBAC)是hierachical和Composite类型的。在引子里面已经介绍了对角色的控制是基于树来执行的,在这里把hierachical和composite的概念放到树上来解释下,如上图是一个角色树。
Hierarchical的意思是角色是可继承的。如果一个用户被分配了图1中的C角色,那他将会拥有C角色所有子角色的权限,即包含FGK的所有权限,注意的一点是FGK的权限总集将会不大于角色C的权限。
Composite的意思是角色是可复合性的。举个例子,用户可以在图中同时被分配了角色G和角色D,他拥有这两个角色对应的权限的合集。

几个问题的讨论。
1. 关于区分部门和部门的员工。我们的rbac模型是基于角色的,因此在角色树中也就没有部门这个概念。对于一个部门来说,对应于角色树的一个子树(subtree),比如图中的C-F- K-G,假设该部门的老大被分配了角色C,那他将会拥有该部门内所有子角色拥有的一切权利;而有的时候,如果有其他需求,比如讨论时提到的部门经理有时候可能不能看到开发团队的代码之类,这种情况下,我们可以把给部门经理分配角色F,他拥有管理其下所有成员的权限,而G节点可能对应的是该部门查看代码权限的角色,具体是什么完全自由扩展。

2.关于工作流中的分配模型。工作流系统中上级部门会将任务分配给下级部门。因为我们的权限控制模型是基于角色的,所以不存在部门的概念,任务的分配只是看你当前的角色是否拥有向下分配任务的许可。在这里我们可以定义一个许可(下发任务),如果某角色定义了这个下发任务的许可,此角色对应的相关人员将会拥有对以此角色为根节点的子树分配任务的权限。还是看C-F-K-G这颗子树,如果我们给C分配了下发任务的许可,则其可以给拥有FGK节点角色的人分配任务,当然你完全可以限制C只给他的直接下属分配任务,那么这个子树就只进行一个level,即C-F-G。

 

关于算法:


树的遍历通常有两种,第一种是按层次遍历,在图中的表示就是从根节点A开始,一层一层的向下走,每一个子节点按照它自己的parent节点来确定位置。通常使用这种遍历会保存节点的路径和该节点的父亲节点ID,对于图中K节点来说,它将会把路径ABCFK和F存储在自己的对象属性中。这种遍历的一个好处就是插入节点很方便,比如我要给K添加一个子节点,只需要查出K的路径,结合K对应的ID就可以了。但是如果是要求查询出一个节点(比如C)的所有子节点呢?很自然的想法是通过数据库的模糊查询找出路径属性包含C的所有记录,不过这样做就出现了一个性能问题,通过这种模糊查询方式速度会很慢。

第二种就是先根遍历,也是在AGILEJ的权限控制里面使用到的。具体的思想就是按照链状来构造树结构。如图所示,这颗树就是按照1-2-3... 20-21-22的顺序来遍历的。对于每个节点我们为其添加了两个属性--左值和右值。现在如果我们要查询节点C的所有子节点,只需要找出数据表中所有左值大于C左值(3)并且右值小于C右值(10)的所有节点即可,这样就避免了使用模糊查询。如果我只是要查出C节点下面所有子节点的数目而非详细信息,那么可以用(C的右值-C的左值-1)/2,即(10-3-1)/2=3,是不是很方便?不过这种算法也有弱点,就是插比起层次遍历的方法要麻烦点。比如我要为H添加一个子节点,那我必须将所有左值大于12的节点的左值加上2,所有右值大于12的节点的右值加2,然后插入一条数据,其左值为14,右值为 15.

简单实现(假设节点C对应的object为roleC):

  • 查询节点c的所有子节点:
    collection = find all role where role.left_value>roleC.leftValue and role.right_value<roleC.rightValue; 
  • 获得节点C的所有子节点个数:
    count = (roleC.rightValue-roleC.leftValue-1)/2
  • 在节点M后插入节点
    update role set role.leftValue=role.leftValue+2 where role.rightValue>roleM.rightValue
    update role set role.rightValue=role.rightValue+2 where role.rightValue>=roleM.rightValue
    now save new Node with leftValue=roleM.leftValue+1 and rightValue=roleM.leftValue+2

转载于:https://www.cnblogs.com/postback/archive/2009/11/05/1596502.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值