RBAC:Role Based Access Control,翻译过来基本上就是基于角色的访问控制系统。
ACL:Access Control List,访问控制列表,是前几年盛行的一种权限设计,它的核心在于用户直接和权限挂钩。RBAC的核心是用户只和角色关联,而角色代表对了权限,这样设计的优势在于使得对用户而言,只需角色即可以,而某角色可以拥有各种各样的权限并可继承。ACL和RBAC相比缺点在于由于用户和权限直接挂钩,导致在授予时的复杂性,虽然可以利用组来简化这个复杂性,但仍然会导致系统不好理解,而且在取出判断用户是否有该权限时比较的困难,一定程度上影响了效率。
我想理一理思路,看看ACL与RBAC的区别:
还是以部门新闻来讨论,对于静态授权,在系统设计做需求分析的时候,往往就可以确定一个系统角色的种类,像新闻系统中,根据需求,可能会有新闻发布者(Publisher),新闻审核者(Reviewer),新闻浏览者(Visitor),管理员(Manager)以及超级管理员(Administrator)。
在设计的时候我们也已经把这些角色与相应的一些Operation绑定在一起。
如:Publisher拥有Publish_Operation Modify_Operation
Reviewer拥有Review_Operation Modify_Operation Delete_Operation
Visitor拥有Visit_Operation,
Manager拥有Create_News_System_Instance_Operation
Modify_News_System_Instance_Operation
Delete_News_System_Instance_Operation
Administrator负责Create_User_Operation
Delete_User_Operation
Assign_Permission_Operation
Deassign_Permission_Operation
Assign_Role_Operation
Deassign_Role_Operation
在授权时,往往先为一个用户(USER),赋予一个角色,如:Manager.这样,USER就拥有了对所有News_Instance(也就是部门新闻)操作的权限。现在假设用户(UserA)访问Create_News_System_Instance功能来创建一个新的新闻实例,叫做采购部门新闻.因为我们在设计的时候就确定,该功能只能由Manager来访问,于是,系统中权限的判断部分会首先判断当前用户(UserA)是否Manager角色,是的话就允许访问,否则显示没有授权的错误信息。
所以,对于Manager这样的应用:
[1]在设计的时候,我们就将这样的角色与相应的Permissions(AlistofSubject-Operationpairs)关联在一起了,这里的Subject是所有的新闻实例(News_Instance),Operation就是Create,Modify以及Delete.
[2]在授权的时候,超级管理员(Administrator)可以利用Assign_Role_Operation将用户(User)与Manager这个角色关联起来。这样,User就拥有了对所有新闻实例的Create,Modify以及Delete操作的权限。
[3]在权限判断的时候,RBAC系统首先判断当前用户是否是设计时确定的角色(这里是Manager),如果是,就允许用户访问,否则就拒绝访问,并显示错误信息。
对于Publisher这样的角色有些不同,Publisher这个角色只与Operation绑定在一起,并没有与具体的Subject相关联,因此,在授权的时候,还需要指定相应的Subject.
所以,对Publisher这样只能事先确定Operation的应用来说:
[1]在设计的时候,我们只能确定该角色能进行哪些操作,而不能确定这些操作实施的对象。
[2]在授权的时候:
[2.1]首先将Publisher与Subject关联,如将Publisher与采购部门新闻关联产生:采购部门新闻_News_Publisher的角色
[2.2]Administrator为用户(User)授于采购部门新闻_News_Publisher角色。从而User拥有了对"采购部门新闻"的发布权限
[3]在权限判断的时候,用户访问采购部门新闻_News_Publish_Operation,系统首先判断该用户是否采购部门新闻_News_Publisher?如果是,就允许用户访问,否则就拒绝访问,并显示错误信息。
这里用到的方法可能是这个样子:
booleancheckPermission(采购部门新闻,Publish_Operation,User){
Listpublishers=RBAC.findRole(newPermission(采购部门新闻,Publish_Operation));
if(publishers==null)returnfalse;
for(Iteratorit=publishers.iterator;it.hasNext();){
Rolepublisher=(Publisher)it.next();
if(publisher.isAssignedWithUser(User)){
returnture;
}
}
returnfalse;
}
假如说,不采用RBAC的做法,考虑一下,使用ACL,那又会是什么样子呢?
对于Manager那样能在设计时就确定Subject与Operation的角色,我认为没有必要考虑ACL了.对于Publisher这样,只能事先确定Operation的角色,我们来做个对比.权限系统要灵活,但是也要简洁,要不然就很可能导至失控。因为嵌套的层次太多,有可能发生不可预知的情况.有一天管理员可能会莫明的发现,怎么这个人会有这个权限的?
所以,我认为在RBAC里不支持Role的层级关系为妙。
好了,现在来看看ACL对Publisher应用
这里指的ACL是直接将User或Group与Subject关联的做法。
User与Subject是多对多的情况,
Group与Subject也是多对多的情况,
同样的,User与Group也是多对多的情况。
现在,还是以采购部门新闻为例:
[1]在授权的时候,可以有以下操作:
[1.1]将User与Subject关联在一起,但是要指定相应的Operation.
如:assignPermission(采购部门新闻,Publish_Operation,User)
[1.2]将Group与Subject关联在一起:
如:assignPermission(采购部门新闻,Publish_Operation,Group)
[1.3]将User与Group关联
如:
assignUserGroup(User,Group)
[2]在权限判断的时候,用户访问采购部门新闻_News_Publish_Operation,系统做如下检查:
booleancheckPermission(采购部门新闻,Publish_Operation,User){
booleanhasPermission=false;
//usersinclude:
//1.PermissiondirectassignedUsers
//2.Theuserassignedwiththegroupsthatassignedwithpermission
Listusers=getAssignedUsers(newPermission(采购部门新闻,Publish_Operation));
hasPermission=users.contains(User)?true:false;
}