权限系统设计模型分析(DAC,MAC,RBAC,ABAC)
此篇⽂章主要尝试将世⾯上现有的⼀些权限系统设计做⼀下简单的总结分析,个⼈⽔平有限,如有错误请不吝指出。
术语
这⾥对后⾯会⽤到的词汇做⼀个说明,⽼司机请直接翻到常见设计模式。
⽤户
发起操作的主体。
对象(Subject)
指操作所针对的客体对象,⽐如订单数据或图⽚⽂件。
权限控制表 (ACL: Access Control List)
⽤来描述权限规则或⽤户和权限之间关系的数据表。
权限 (Permission)
⽤来指代对某种对象的某⼀种操作,例如“添加⽂章的操作”。
权限标识
权限的代号,例如⽤“ARTICLE_ADD”来指代“添加⽂章的操作”权限。
常见设计模式
⾃主访问控制(DAC: Discretionary Access Control)
系统会识别⽤户,然后根据被操作对象(Subject)的权限控制列表(ACL: Access Control List)或者权限控制矩阵(ACL: Access Control Matrix)的信息来决定⽤户的是否能对其进⾏哪些操作,例如读取或修改。
⽽拥有对象权限的⽤户,⼜可以将该对象的权限分配给其他⽤户,所以称之为“⾃主(Discretionary)”控制。
这种设计最常见的应⽤就是⽂件系统的权限设计,如微软的NTFS。
DAC最⼤缺陷就是对权限控制⽐较分散,不便于管理,⽐如⽆法简单地将⼀组⽂件设置统⼀的权限开放给指定的⼀⽤户。
Windows的⽂件权限
强制访问控制(MAC: Mandatory Access Control)
MAC是为了弥补DAC权限控制过于分散的问题⽽诞⽣的。在MAC的设计中,每⼀个对象都都有⼀些权限标识,每个⽤户同样也会有⼀些权限标识,⽽⽤户能否对该对象进⾏操作取决于双⽅的权限标识的关系,这个限制判断通常是由系统硬性限制的。⽐如在影视作品中我们经常能看到特⼯在查询机密⽂件时,屏幕提⽰需要“⽆法访问,需要⼀级安全许可”,这个例⼦中,⽂件上就有“⼀级安全许可”的权限标识,⽽⽤户并不具有。
MAC⾮常适合机密机构或者其他等级观念强烈的⾏业,但对于类似商业服务系统,则因为不够灵活⽽不能适⽤。
RedHat MLS
基于⾓⾊的访问控制(RBAC: Role-Based Access Control)
因为DAC和MAC的诸多限制,于是诞⽣了RBAC,并且成为了迄今为⽌最为普及的权限设计模型。
RBAC在⽤户和权限之间引⼊了“⾓⾊(Role)”的概念(暂时忽略Session这个概念):
RBAC核⼼设计
如图所⽰,每个⽤户关联⼀个或多个⾓⾊,每个⾓⾊关联⼀个或多个权限,从⽽可以实现了⾮常灵活的权限管理。⾓⾊可以根据实际业务需求灵活创建,这样就省去了每新增⼀个⽤户就要关联⼀遍所有权限的⿇烦。简单来说RBAC就是:⽤户关联⾓⾊,⾓⾊关联权限。另外,RBAC是可以模拟出DAC和MAC的效果的。
权限标识说明
find具有此权限的⽤户可以运⾏所有和查询有关的命令,如:aggregate、checkShardingIndex、count等。
insert具有此权限的⽤户可以运⾏所有和新建数据有关的命令:insert和create等。
collStats具有此权限的⽤户可以对指定database或collection执⾏collStats命令。
viewRole具有此权限的⽤户可以查看指定database的⾓⾊信息。
…
⾓⾊find insert collStats viewRole…
read✔✔…
readWrite✔✔✔…
dbAdmin✔✔…
userAdmin✔…
最后授予⽤户不同的⾓⾊,就可以实现不同粒度的权限分配了。
⽬前市⾯上绝⼤部分系统在设计权限系统时都采⽤RBAC模型。然⽽也有的系统错误地实现了RBAC,他们采⽤的是判断⽤户是否具有某个⾓⾊⽽不是判断权限,例如以下代码:
<?php
if ($user->hasRole('hr')) {
// 执⾏某种只有“HR”⾓⾊才能做的功能,例如给员⼯涨薪…
// ...
广东旅游景点排行}
如果后期公司规定部门经理也可以给员⼯涨薪,这时就不得不修改代码了。
以上基本就是RBAC的核⼼设计(RBAC Core)。⽽基于核⼼概念之上,RBAC规范还提供了扩展模式。
⾓⾊继承(Hierarchical Role)
RBAC 1
顾名思义,⾓⾊继承就是指⾓⾊可以继承于其他⾓⾊,在拥有其他⾓⾊权限的同时,⾃⼰还可以关联额外的权限。这种设计可以给⾓⾊分组和分层,⼀定程度简化了权限管理⼯作。
职责分离(Separation of Duty)
为了避免⽤户拥有过多权限⽽产⽣利益冲突,例如⼀个篮球运动员同时拥有裁判的权限(看⼀眼就给你判犯规狠不狠?),另⼀种职责分离扩展版的RBAC被提出。
职责分离有两种模式:
安徽二本大学排名静态职责分离(Static Separation of Duty):⽤户⽆法同时被赋予有冲突的⾓⾊。
动态职责分离(Dynamic Separation of Duty):⽤户在⼀次会话(Session)中不能同时激活⾃⾝所拥有的、互相有冲突的⾓⾊,只能选择其⼀。RBAC 2
RBAC 3
讲了这么多RBAC,都还只是在⽤户和权限之间进⾏设计,并没有涉及到⽤户和对象之间的权限判断,⽽在实际业务系统中限制⽤户能够使⽤的对象是很常见的需求。例如华中区域的销售没有权限查询华南区域的客户数据,虽然他们都具有销售的⾓⾊,⽽销售的⾓⾊拥有查询客户信息的权限。
那么我们应该怎么办呢?
⽤户和对象的权限控制
在RBAC标准中并没有涉及到这个内容(RBAC基本只能做到对⼀类对象的控制),但是这⾥讲⼏种基于RBAC的实现⽅式。
<?php
$auth=Yii::app()->authManager;
$auth->createOperation('createPost','create a post');
$auth->createOperation('readPost','read a post');
$auth->createOperation('updatePost','update a post');
$auth->createOperation('deletePost','delete a post');
// 主要看这⾥。
// 这⾥创建了⼀个名为`updateOwnPost`的权限,并且写了⼀段代码⽤来检验⽤户是否为该帖⼦的作者
$bizRule='return Yii::app()->user->id==$params["post"]->authID;';
$task=$auth->createTask('updateOwnPost','update a post by author himself',$bizRule);
$task->addChild('updatePost');
$role=$auth->createRole('reader');
$role->addChild('readPost');
$role=$auth->createRole('author');
$role->addChild('reader');
$role->addChild('createPost');
$role->addChild('updateOwnPost');
$role=$auth->createRole('editor');
$role->addChild('reader');
$role->addChild('updatePost');
$role=$auth->createRole('admin');
$role->addChild('editor');
$role->addChild('author');
$role->addChild('deletePost');
实现效果:
Yii 1.X权限图
在这个Yii的官⽅例⼦中,updateOwnPost在判断⽤户是否具有updatePost权限的基础上更进⼀步判断了⽤户是否有权限操作这个特定的对象,并且这个判断逻辑是通过代码设置的,⾮常灵活。
不过⼤部分时候我们并不需要这样的灵活程度,会带来额外的开发和维护成本,⽽另⼀种基于模式匹配规则的对象权限控制可能更适合。例如判断⽤户是否对Id为123的⽂章具有编辑的权限,代码可能是这样的:
<?php
// 假设articleId是动态获取的
$articleId = 123;
if ($user->can("article:edit:{$articleId}")) {
// ...
}
⽽给⽤户授权则有多种⽅式可以选择:
<?php
// 允许⽤户编辑Id为123的⽂章
$user->grant('article:edit:123');
// 使⽤通配符,允许⽤户编辑所有⽂章
哪个牌子的防晒霜好用$user->grant('article:edit:*');
虽然不及Yii⽅案的灵活,但某些场景下这样就够⽤了。
如果⼤家还有更好的⽅案,欢迎在评论中提出。
基于属性的权限验证(ABAC: Attribute-Based Access Control)
ABAC被⼀些⼈称为是权限系统设计的未来。
不同于常见的将⽤户通过某种⽅式关联到权限的⽅式,ABAC则是通过动态计算⼀个或⼀组属性来是否满⾜某种条件来进⾏授权判断(可以编写简单的逻辑)。属性通常来说分为四类:⽤户属性(如⽤户年龄),环境属性(如当前时间),操作属性(如读取)和对象属性(如⼀篇⽂章,⼜称资源属性),所以理论上能够实现⾮常灵活的权限控制,⼏乎能满⾜所有类型的需求。
例如规则:“允许所有班主任在上课时间⾃由进出校门”这条规则,其中,“班主任”是⽤户的⾓⾊属性,“上课时间”是环境属性,“进出”是操作属性,
⽽“校门”就是对象属性了。为了实现便捷的规则设置和规则判断执⾏,ABAC通常有配置⽂件(XML、YAML等)或DSL配合规则解析引擎使⽤。XACML(eXtensible Access Control Markup Language)是ABAC的⼀个实现,但是该设计过于复杂,我还没有完全理解,故不做介绍。
总结⼀下,ABAC有如下特点:
1. 集中化管理
网络游戏前十名>花呗额度怎么快速提升2. 可以按需实现不同颗粒度的权限控制
3. 不需要预定义判断逻辑,减轻了权限系统的维护成本,特别是在需求经常变化的系统中
4. 定义权限时,不能直观看出⽤户和对象间的关系
5. 规则如果稍微复杂⼀点,或者设计混乱,会给管理者维护和追查带来⿇烦
6. 权限判断需要实时执⾏,规则过多会导致性能问题
宣化区教育局既然ABAC这么好,那最流⾏的为什么还是RBAC呢?
ABAC有时也被称为PBAC(Policy-Based Access Control)或CBAC(Claims-Based Access Control)。
结语
权限系统设计可谓博⼤精深,这篇⽂章只是介绍了⼀点⽪⽑。
随着⼈类在信息化道路上越⾛越远,权限系统的设计也在不断创新,但⽬前好像处在了平台期。
可能因为在RBAC到ABAC之间有着巨⼤的鸿沟,⽆法轻易跨越,也可能是⼀些基于RBAC的微创新⽅案还不够规范化从⽽做到普及。不过在服务化架构的浪潮下,未来这⼀块必然有极⾼的需求,也许巨头们已经开始布局了。
参考⽂档
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论