目录

  1. 概述
    1. 权限管理解决方案
    2. RBAC 初探
    3. ABAC 初探
  2. 权限控制的分类
    1. 从控制力度对权限管理分类
    2. 从控制方向对权限管理分类
  3. RBAC 模型概述
    1. RBAC 模型族
      1. RBAC0
      2. RBAC1
      3. RBAC2
      4. RBAC3
  4. RBAC 的设计思路
  5. RBAC 用户角色权限设计方案
  6. 角色组
  7. 如何选择合适的权限模型?
  8. 总结
  9. 附录

概述

❓什么是权限控制(管理)?

权限管理,一般指根据系统设置的安全规则或安全策略,用户可以访问而且只能访问自己被授权的资源。权限管理几乎出现在任何有用户和密码的系统里面。不要将权限管理与用户身份认证密码加密系统管理等概念混淆

简而言之,权限管理主要工作是:根据系统设置的安全规则或者安全策略,限制用户的访问资源

❓为什么需要权限控制(管理)?

如何没有权限控制,那么此系统中的任何一个用户都拥有所有的权限,这是所有人不能接收的,所以需要相应的权限控制方法

❓什么时候需要进行权限控制?

如果已经构建了用户系统,某个时刻 API 就需要判断当前访问的用户是否能够访问当前资源,这时候就需要构建自己的权限系统,权限系统中一个很重要的概念就是授权,授权指的是判断用户具备那些权限的过程与认证是两个完全不同的含义

权限管理解决方案

权限控制问题已经存在很久,现存最常用的权限控制模型有:基于角色的访问控制(RBAC: Role-Based Access Control)基于属性的权限验证(ABAC: Attribute-Based Access Control)

RBAC 初探

❓什么是 RBAC(Role-based access control)?

RBAC 是目前公认的解决大型企业的统一资源访问控制的有效方法,RBAC 不同于传统的强制访问控制自由选定访问控制的控制方案(直接赋予使用者权限),而是将权限赋予角色。在 RBAC 方法中,权限与角色相关联,用户通过成为适当角色的成员而得到这些角色的权限,具体的细节展示在下图

👍使用 RBAC 之后,将会极大地简化系统的权限管理。用户可以很容易地从一个角色指派到另一个角色,并且角色可根据新的需求和系统的合并从而赋予新的权限,而权限也可根据需要而从某角色中回收。

ABAC 初探

在 ABAC 权限模型下,可以轻松地实现以下权限控制逻辑:

  1. 编辑 A 具有某本书的编辑权限;
  2. 当一个文档的所属部门跟用户的部门相同时,用户可以访问这个文档
  3. 当用户是一个文档的拥有者并且文档的状态是草稿,用户可以编辑这个文档
  4. 早上九点前禁止 A 部门的人访问 B 系统
  5. 在除了上海以外的地方禁止以管理员身份访问 A 系统

✨上述的逻辑中有几个共同点:

  1. 具体到某一个而不是某一类资源
  2. 具体到某一个操作
  3. 能通过请求的上下文(如时间、地理位置、资源 Tag)动态执行策略

基于属性的权限控制可以细粒度地授权在某种情况下对某个资源具备某个特定的权限

🆚基于属性的权限验证和基于角色的访问控制两者各有优劣:

RBAC 模型构建起来更加简单,缺点在于无法做到对资源细粒度地授权(都是授权某一类资源而不是授权某一个具体的资源);ABAC 模型构建相对复杂,学习成本高,优点在于细粒度和根据上下文动态执行

权限控制的分类

从不同角度看待同一个事物存在不同的分歧,以下给出百度百科给出的两种权限控制的分类

从控制力度对权限管理分类

✨从控制力度来看,可以将权限管理分为两大类:

  1. 功能级权限管理
  2. 数据级权限管理

数据级权限管理某个用户能够访问和操作哪些数据。通常来说,数据权限由用户所属的组织来确定。比如:生产部只能看自己部门的生产数据;销售部门只能看销售数据。公司的总经理可以看所有的数据,数据级权限管理间接性的保证了数据隔离。在实际的业务系统中,数据权限往往更加复杂,非常有可能销售部门可以看生产部门的数据,以确定销售策略、安排计划等

为了面对复杂的需求,数据权限的控制通常是由程序员书写个性化的 SQL 来限制数据范围的,而不是交给权限模型来控制。当然也可以从权限模型或者权限框架的角度去解决这个问题,但适用性有限

从控制方向对权限管理分类

✨从控制方向来看,也可以将权限管理分为两大类:

  1. 从系统获取数据,比如查询订单、查询客户资料
  2. 向系统提交数据,比如删除订单、修改客户资料

RBAC 模型概述

RBAC 认为权限的过程可以抽象概括为:判断Who 是否可以对 What 进行 How 的访问操作这个逻辑表达式的值是否为True的求解过程,即将权限问题转换为Who、What、How 的问题。其中who、what、how构成了访问权限三元组

✨RBAC 支持公认的安全原则:最小特权原则责任分离原则数据抽象原则

  • 最小特权原则得到支持,是因为在 RBAC 模型中可以通过限制分配给角色权限的多少和大小来实现,分配给某用户对应的角色的权限只要不超过该用户完成其任务的需要就可以了
  • 责任分离原则得到支持,是因为在 RBAC 模型中可以通过在完成敏感任务过程中分配两个责任上互相约束的两个角色来实现,例如在清查账目时,只需要设置财务管理员和会计两个角色参加就可以了
  • 数据抽象得到支持,是借助于抽象许可权这样的概念实现的。如在账目管理活动中,可以使用信用、借方等抽象许可权,而不是使用操作系统提供的读、写、执行等具体的许可权。但 RBAC 并不强迫实现这些原则,安全管理员可以允许配置 RBAC 模型使它不支持这些原则。因此,RBAC 支持数据抽象的程度与 RBAC 模型的实现细节有关

RBAC 模型族

✨RBAC96 是一个模型族,其中包括 RBAC0 ~ RBAC3 四个概念性模型:

  1. 基本模型 RBAC0 定义了完全支持 RBAC 概念的任何系统的最低需求
  2. RBAC1 和 RBAC2 两者都包含 RBAC0,但各自都增加了独立的特点,它们被称为高级模型。其中 RBAC1 中增加了角色分级的概念,一个角色可以从另一个角色继承许可权;RBAC2 中强调在 RBAC 的不同组件中配置方面的一些限制
  3. RBAC3 称为统一模型,它包含了 RBAC1 和 RBAC2,利用传递性,也把 RBAC0 包括在内

RBAC0

RBAC0 定义了能构成一个 RBAC 控制系统的最小的元素集合,在 RBAC 之中,包含用户 users(USERS)、角色 roles(ROLES)、目标 objects(OBS)、操作 operations(OPS)、许可权 permissions(PRMS) 五个基本数据元素,此模型指明用户、角色、访问权限和会话之间的关系

组件含义
用户(User)系统接口及访问的操作者
角色(Role)具有一类相同操作权限的用户的总称
权限(Permission)能够访问某接口或者做某操作的授权资格
会话(Session)RABC0 权限管理的核心部分,其他的版本都是建立在 RBAC0 的基础上的

对应的 UML 类图如下:

每个角色至少具备一个权限,每个用户至少扮演一个角色;可以对两个完全不同的角色分配完全相同的访问权限;会话由用户控制,一个用户可以创建会话并激活多个用户角色,从而获取相应的访问权限,用户可以在会话中更改激活角色,并且用户可以主动结束一个会话。用户和角色是多对多的关系,表示一个用户在不同的场景下可以拥有不同的角色

例如项目经理也可以是项目架构师等;当然了一个角色可以给多个用户,例如一个项目中有多个组长,多个组员等

🎶将用户和权限进行分离,是彼此相互独立,使权限的授权认证更加灵活

角色和许可(权限)是多对多的关系,表示角色可以拥有多分权利,同一个权利可以授给多个角色都是非常容易理解的,想想现实生活中,当官的级别不同的权限的情景,其实这个模型就是对权限这方面的一个抽象,联系生活理解就非常容易了

RBAC1

RBAC1 基于 RBAC0 模型,引入角色间的继承关系,即角色之间有了上下级的区别,角色间的继承关系可分为一般继承关系受限继承关系。这种模型合适于角色之间的层次明确,包含明确

🆚一般继承关系与受限继承关系异同

  • 一般继承关系仅要求角色继承关系是一个绝对偏序关系,允许角色间的多继承
  • 受限继承关系则进一步要求角色继承关系是一个树结构,实现角色间的单继承

RBAC2

RBAC2 基于 RBAC0 模型进行了角色的访问控制

RBAC2 模型中添加了责任分离关系。RBAC2 的约束规定了权限被赋予角色时,或角色被赋予用户时,以及当用户在某一时刻激活一个角色时所应遵循的强制性规则。责任分离包括静态责任分离动态责任分离

约束与用户—角色—权限关系一起决定了 RBAC2 模型中用户的访问许可,此约束有多种:

  • 互斥角色 :同一用户只能分配到一组互斥角色集合中至多一个角色,支持责任分离的原则。互斥角色是指各自权限互相制约的两个角色。对于这类角色一个用户在某一次活动中只能被分配其中的一个角色,不能同时获得两个角色的使用权。例如:在审计活动中,一个角色不能同时被指派给会计角色和审计员角色
  • 基数约束 :一个角色被分配的用户数量受限;一个用户可拥有的角色数目受限;同样一个角色对应的访问权限数目也应受限,以控制高级权限在系统中的分配
  • 先决条件角色 :可以分配角色给用户仅当该用户已经是另一角色的成员;对应的可以分配访问权限给角色,仅当该角色已经拥有另一种访问权限。要想获得较高的权限,要首先拥有低一级的权限
  • 运行时互斥 :例如,允许一个用户具有两个角色的成员资格,但在运行中不可同时激活这两个角色

RBAC3

RBAC3 是最全面级的权限管理,它是基于 RBAC0 的基础上,将 RBAC1 和 RBAC2 进行整合了,也是最复杂的,可以简单的理解:RBAC3 = RBAC1 + RBAC2

RBAC 的设计思路

🎶一个 RBAC 权限模型核心授权逻辑仅考虑以下三点

  1. 某用户扮演什么角色?
  2. 某角色具有什么权限?
  3. 通过角色的权限推到用户的权限

以一个简单的场景(Gitlab 的权限系统)为例,用户系统中有 Admin、Maintainer、Operator 三种角色,这三种角色分别具备不同的权限,比如只有 Admin 具备创建代码仓库、删除代码仓库的权限,其他的角色都不具备

授予某个用户 Admin 这个角色,他就具备了创建代码仓库删除代码仓库这两个权限

基于角色的访问控制基本原理是在用户和访问权限之间加入角色这一层,实现用户和权限的分离,用户只有通过激活角色才能获得访问权限。通过角色对权限分组,大大简化了用户权限分配表,间接地实现了对用户的分组,提高了权限的分配效率。并且加入角色层后,访问控制机制更接近真实世界中的职业分配,便于权限管理

在 RBAC 模型中,角色是系统根据管理中相对稳定的职权和责任来划分,每种角色可以完成一定的职能。用户通过饰演不同的角色获得角色所拥有的权限,一旦某个用户成为某角色的成员,则此用户可以完成该角色所具有的职能。通过将权限指定给角色而不是用户,在权限分派上提供了极大的灵活性和极细的权限指定粒度

RBAC 用户角色权限设计方案

一个用户拥有若干角色,每一个角色拥有若干权限。这样,就构造成用户-角色-权限的授权模型。在这种模型中,用户与角色之间,角色与权限之间,一般者是多对多的关系,如下图

❓到底什么是角色?

可以理解为一定数量的权限的集合,权限的载体。例如:一个论坛系统,超级管理员版主都是角色。版主可管理版内的帖子、可管理版内的用户等,这些是权限。要给某个用户授予这些权限,不需要直接将权限授予用户,可将版主这个角色赋予该用户

当用户的数量非常大时,要给系统每个用户逐一授权(授角色),是件非常烦琐的事情。这时,就需要给用户分组,每个用户组内有多个用户。除了可给用户授权外,还可以给用户组授权。这样一来,用户拥有的所有权限,就是用户个人拥有的权限与该用户所在用户组拥有的权限之和。(下图为用户组、用户与角色三者的关联关系)

❓在应用系统中,权限表现成什么?

对功能模块的操作,对上传文件的删改,菜单的访问,甚至页面上某个按钮、某个图片的可见性控制,都可属于权限的范畴。有些权限设计,会把功能操作作为一类,而把文件、菜单、页面元素等作为另一类,这样构成“用户-角色-权限-资源”的授权模型。而在做数据表建模时,可把功能操作和资源统一管理,也就是都直接与权限表进行关联,这样可能更具便捷性和易扩展性

权限表中有一列权限类型,我们根据它的取值来区分是哪一类权限,如MENU表示菜单的访问权限、OPERATION表示功能模块的操作权限、FILE表示文件的修改权限、ELEMENT表示页面元素的可见性控制等。这样设计的好处有二

  1. 不需要区分哪些是权限操作,哪些是资源,(实际上,有时候也不好区分,如菜单,把它理解为资源呢还是功能模块权限呢?)
  2. 方便扩展,当系统要对新的东西进行权限控制时,我只需要建立一个新的关联表权限 XX 关联表,并确定这类权限的权限类型字符串。

🎶这里要注意的是,权限表与权限菜单关联表、权限菜单关联表与菜单表都是一对一的关系。(文件、页面权限点、功能操作等同理)。也就是每添加一个菜单,就得同时往这三个表中各插入一条记录。这样,可以不需要权限菜单关联表,让权限表与菜单表直接关联,此时,须在权限表中新增一列用来保存菜单的 ID,权限表通过权限类型和这个 ID 来区分是种类型下的哪条记录。如此,RBAC 权限模型的扩展模型的完整设计图如下:

下图是另一种设计方案

角色组

随着系统的日益庞大,为了方便管理,可引入角色组对角色进行分类管理,跟用户组不同,角色组不参与授权

例如:某电网系统的权限管理模块中,角色就是挂在区局下,而区局在这里可当作角色组,它不参于权限分配。另外,为方便上面各主表自身的管理与查找,可采用树型结构,如菜单树、功能树等,当然这些可不需要参于权限分配。

❓角色和用户组有什么区别?

两者的主要差别是:用户组是用户的集合,但不是许可权的集合;而角色却同时具有用户集合和许可权集合的概念,角色的作用把这两个集合联系在一起的中间媒介

在一个系统中,如果用户组的许可权和成员仅可以被系统安全员修改的话,在这种机制下,用户组的机制是非常接近于角色的概念的。角色也可以在用户组的基础上实现,这有利于保持原有系统中的控制关系。在这种情况下,角色相当于一个策略部件,与用户组的授权及责任关系相联系,而用户组是实现角色的机制,因此,两者之间是策略与实现机制之间的关系

如何选择合适的权限模型?

组织的规模是至关重要的因素。由于 ABAC 最初的设计和实施困难,对于小型企业而言,考虑起来可能太复杂了。对于中小型企业,RBAC 是 ABAC 的简单替代方案,每个用户都有一个唯一的角色,并具有相应的权限和限制。当用户转移到新角色时,其权限将更改为新职位的权限。这意味着,在明确定义角色的层次结构中,可以轻松管理少量内部和外部用户。

但是,当必须手动建立新角色时,对于大型组织而言,效率不高。一旦定义了属性和规则,当用户和利益相关者众多时,ABAC 的策略就更容易应用,同时还降低了安全风险

简而言之,如果满足以下条件,请选择 ABAC:

  • 在一个拥有许多用户的大型组织中
  • 需要深入的特定访问控制功能
  • 有时间投资远距离的模型
  • 需要确保隐私和安全合规

如果满足以下条件,请考虑 RBAC:

  • 所在的是中小型企业
  • 访问控制策略广泛
  • 外部用户很少,并且组织角色得到了明确定义

总结

不良的权限管理系统,必然留下系统漏洞,给黑客可趁之机。很多软件可以轻松通过 URL 侵入、SQL 注入等模式,轻松越权获得未授权数据。甚至对系统数据进行修改、删除,造成巨大损失。很多系统,尤其是采用硬编码方式的系统,存在权限逻辑与业务代码紧密耦合,同时又分散在系统各个地方,系统漏洞势必非常多,而且随着系统不断修改,漏洞逐步增多。

好的系统,应该将权限逻辑集中起来,由专业的安全引擎进行设置和解析。业务逻辑调用安全引擎,获得权限结果,不再使用非专业模式。

附录

权限系统与 RBAC 模型概述

如何对用户进行权限管理

图文详解基于角色的权限控制模型 RBAC

Role-based access control wiki

产品 | 权限设计=功能权限+数据权限