权限模型(RBAC/ABAC)

最近研究了一下权限模型,看完AWS IAM之后,深感 AWS IAM 设计精妙。就我个人的看法,RBAC应对一些场景还是不太够,主要是控制 粒度不够,例如,我想控制某个role只能操作某个集群的资源,RBAC就无法表达。ABAC可以表达,但是ABAC要复杂很多,AWS IAM是ABAC, 但是易用性上做的很不错,还有一种方式,就是魔改RBAC,通过增加一个condition来缩小权限,从而做到精细化控制。

这其实就是一种融合了RBAC和ABAC的权限模型。不过,我们还是从头开始,一步一步来讲。

权限模型有很多,光是 Wikipedia 就列了12条。我们挑几个来讲。

ACL(Access Control List)

ACL 是指,对于每一个对象,我们都保存一个可访问列表,比如:/home/jiajun/.vimrc 允许用户A、B和C访问。我们将这些存储起来, 在检验权限时,依次检查列表中是否有对应用户,从而得知用户是否具有对某对象的某种权限。

MAC(Mandatory Access Control)

MAC 有很多的解释,但是没有几个说的很清楚的。查阅大量英文资料之后,我来说说我的理解。MAC和ACL有一点点类似,但是区别在于 MAC 给某个对象设定了一个安全等级,当检验权限时,检查用户是否有对应的身份等级,如果有,则允许访问,否则拒绝。

此外MAC同样会有权限的概念,例如持有最高等级权限的人,同时拥有对于某对象的写入权限,那么访问时,便可以通过。

RBAC(Role Based Access Control)

RBAC 是很常见的一种授权方式,我之前做过此类系统。对于普通授权,都是建立用户和对象之间的关系,比如:

用户A -> 能读取 -> 文件a
用户B -> 能写入 -> 文件a
用户A -> 能删除 -> 文件b

这样的控制能做到很细的粒度,但是有一个缺点,那就是难于控制。举个例子,对于企业内部系统,假设普通员工们都可以访问100个 子系统接口,对于一个新来的员工,我们就需要给他重新配置这100个子系统接口的权限。但是有了RBAC之后就不一样了,我们通过 引入role这一个中间层,所有的授权关系,我们都是建立在 role 和 对象之间,例如:

角色A -> 能读取 -> 文件a
角色B -> 能写入 -> 文件a
角色A -> 能删除 -> 文件b

然后我们再建立用户和角色之间的关系。这样,对于一个新来的员工,我们只需要把他和对应的角色关联起来,他就自动拥有了该角色 所有的权限。

但是RBAC的缺点在于,赋予权限之后,无法将权限的粒度限制到更小,例如,我们允许用户A “删除集群”,但是RBAC上,我们无法表述 出 “删除1号集群” 的操作,也就是说,RBAC无法做到缩小权限。

ABAC(Attribute Based Access Control)

Attribute ,也就是对象的各种属性,包括执行时的各种属性。ABAC的复杂性就在于此,因为属性是无限多的,根据各种属性来判断 权限是否足够,需要涉及到需要非常多的判断和规则,以及优先级处理问题。但是AWS IAM仍然做到了易用,IAM本身更偏向于ABAC实现, 但是通过policy, user/user group/role 抽象之后,整个系统的行为非常像 RBAC。

总结

通过上面的表述,我们可以看到,RBAC易用性很高,配置简单,但是无法精细的控制权限;而ABAC可以做到事无巨细,控制粒度可以 做到非常精细,但是实现起来会很复杂,但是抽象的比较好的系统,例如IAM,在易用性上也还是不错的。

我个人认为对于绝大部分公司的业务场景,RBAC已经足够,如果想要更细粒度的控制,可以融合RBAC和ABAC两种控制模型,鉴于实现 难度,可以考虑基于RBAC,往ABAC靠,例如引入condition来进行权限缩小。


ref:


微信公众号
关注公众号,获得及时更新

更多文章
  • Golang(Go语言)中实现典型的fork调用
  • 软件开发之禅---大事化小,各个击破
  • 程序员的自我修养:链接,装载与库 阅读笔记
  • Redis源码阅读与分析三:哈希表
  • Redis源码阅读与分析一:sds
  • Redis源码阅读与分析二:双链表
  • Golang runtime 源码阅读与分析
  • Golang的一些坑
  • GC 垃圾回收
  • 设计一个路由
  • Go语言性能优化实战
  • 那些年开发的时候踩过的坑
  • (关系型)数据库优化总结
  • 动态规划民科教程
  • Golang 分布式异步任务队列 Machinery 教程