权限系统设计模型分析(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 最大缺陷就是对权限控制比较分散,不便于管理,比如无法简单地将一组文件设置统一的权限开放给指定的一群用户。

强制访问控制(MAC: Mandatory Access Control)

MAC 是为了弥补 DAC 权限控制过于分散的问题而诞生的。在 MAC 的设计中,每一个对象都都有一些权限标识,每个用户同样也会有一些权限标识,而用户能否对该对象进行操作取决于双方的权限标识的关系,这个限制判断通常是由系统硬性限制的。比如在影视作品中我们经常能看到特工在查询机密文件时,屏幕提示需要 “无法访问,需要一级安全许可”,这个例子中,文件上就有“一级安全许可” 的权限标识,而用户并不具有。

MAC 非常适合机密机构或者其他等级观念强烈的行业,但对于类似商业服务系统,则因为不够灵活而不能适用。

Red Hat: MLS

基于角色的访问控制(RBAC: Role-Based Access Control)

因为 DAC 和 MAC 的诸多限制,于是诞生了 RBAC,并且成为了迄今为止最为普及的权限设计模型。

RBAC是Role-BasedAccess Control的英文缩写,意思是基于角色的访问控制。

简单的理解其理念就是将“角色”这个概念赋予用户,在系统中用户与权限之间通过角色进行关联,以这样的方法来实现灵活配置。

RBAC权限模型是基于角色的权限控制。模型中有几个关键的术语:

  • 用户:系统接口及访问的操作者
  • 权限:能够访问某接口或者做某操作的授权资格
  • 角色:具有一类相同操作权限的用户的总称

RBAC0是RBAC权限模型的核心思想,RBAC1、RBAC2、RBAC3都是在RBAC0上进行扩展的。RBAC0是由四部分构成:用户、角色、会话、许可。

用户和角色的含义很简单,通过字面意思即可明白,会话:指用户被赋予角色的过程,称之为会话或者是说激活角色;许可:就是角色拥有的权限(操作和和被控制的对象),简单的说就是用户可使用的功能或者可查看的数据。

用户与角色是多对多的关系,用户与会话是一对一的关系,会话与角色是一对多的关系,角色与许可是多对多的关系。

权限系统设计模型分析(DAC,MAC,RBAC,ABAC)_第1张图片

 

RBAC 在用户和权限之间引入了 “角色(Role)” 的概念(暂时忽略 Session 这个概念):

权限系统设计模型分析(DAC,MAC,RBAC,ABAC)_第2张图片

图片来自 Apache Directory

如图所示,每个用户关联一个或多个角色,每个角色关联一个或多个权限,从而可以实现了非常灵活的权限管理。角色可以根据实际业务需求灵活创建,这样就省去了每新增一个用户就要关联一遍所有权限的麻烦。简单来说 RBAC 就是:用户关联角色,角色关联权限。另外,RBAC 是可以模拟出 DAC 和 MAC 的效果的。

例如数据库软件 MongoDB 便是采用 RBAC 模型,对数据库的操作都划分成了权限(MongoDB 权限文档):

权限标识 说明
find 具有此权限的用户可以运行所有和查询有关的命令,如:aggregate、checkShardingIndex、count 等。
insert 具有此权限的用户可以运行所有和新建数据有关的命令:insert 和 create 等。
collStats 具有此权限的用户可以对指定 database 或 collection 执行 collStats 命令。
viewRole 具有此权限的用户可以查看指定 database 的角色信息。

基于这些权限,MongoDB 提供了一些预定义的角色(MongoDB 预定义角色文档,用户也可以自己定义角色):

角色 find insert collStats viewRole
read
readWrite
dbAdmin
userAdmin

最后授予用户不同的角色,就可以实现不同粒度的权限分配了。

目前市面上绝大部分系统在设计权限系统时都采用 RBAC 模型

以上基本就是 RBAC 的核心设计(RBAC Core)。而基于核心概念之上,RBAC 规范还提供了扩展模式。

角色继承 (Hierarchical Role)

带有角色继承的 RBAC。图片来自 Apache Directory

顾名思义,角色继承就是指角色可以继承于其他角色,在拥有其他角色权限的同时,自己还可以关联额外的权限。这种设计可以给角色分组和分层,一定程度简化了权限管理工作。

职责分离 (Separation of Duty)

为了避免用户拥有过多权限而产生利益冲突,例如一个篮球运动员同时拥有裁判的权限(看一眼就给你判犯规狠不狠?),另一种职责分离扩展版的 RBAC 被提出。

职责分离有两种模式:

  • 静态职责分离 (Static Separation of Duty):用户无法同时被赋予有冲突的角色。
  • 动态职责分离 (Dynamic Separation of Duty):用户在一次会话(Session)中不能同时激活自身所拥有的、互相有冲突的角色,只能选择其一。

基于属性的权限验证(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. 权限判断需要实时执行,规则过多会导致性能问题

你可能感兴趣的:(软件架构,网络,设计模式,架构)