ShiningDan的博客

权限系统设计调研文档

  1. RBAC 模型
  2. 操作系统(Linux 为例)

RBAC 模型

迄今为止最为普及的权限设计模型是RBAC模型,基于角色的访问控制(Role-Based Access Control)

RBAC支持三个著名的安全原则:最小权限原则,责任分离原则和数据抽象原则。

RBAC0 模型

最基础也是最核心的模型,包括用户/角色/权限

  • 用户:发起操作的主体
  • 角色:连接了用户和权限的关系
  • 权限:用户可以访问的资源,包括页面权限、操作权限、数据权限

除此以外,还有两个必不可少的概念,就是操作和资源

  • 资源:被操作的对象
  • 操作:对资源的动作。权限代表的即为是否可以对资源进行操作

基于核心概念之上、RBAC还提供了扩展模式。包括RBAC1、RBAC2、RBAC3模型

RBAC1 模型

此模型引入了角色继承(Hierarchical Role)概念,即角色具有上下级的关系

这种设计可以给角色分组和分层,一定程度简化了权限管理工作。

RBAC2 模型

基于核心模型的基础上,进行了角色的约束控制,RBAC2模型中添加了责任分离关系:

  • 互斥角色: 同一用户只能分配到一组互斥角色集合中至多一个角色,支持责任分离的原则。互斥角色是指各自权限互相制约的两个角色。比如财务部有会计和审核员两个角色,他们是互斥角色,那么用户不能同时拥有这两个角色,体现了职责分离原则
  • 基数约束: 一个角色被分配的用户数量受限;一个用户可拥有的角色数目受限;同样一个角色对应的访问权限数目也应受限,以控制高级权限在系统中的分配
  • 先决条件角色: 即用户想获得某上级角色,必须先获得其下一级的角色

RBAC3 模型

即最全面的权限管理,它是基于 RBAC0,将 RBAC1 和 RBAC2 进行了整合

包含 组织/职位/用户组 的模型

用户组一般和组织绑定。有一部分人具有相同的属性,比如财务部的所有员工。如果直接给用户分配角色,管理员的工作量就会很大。如果把相同属性的用户归类到某用户组,那么管理员直接给用户组分配角色,用户组里的每个用户即可拥有该角色,以后其他用户加入用户组后,即可自动获取用户组的所有角色,退出用户组,同时也撤销了用户组下的角色。

根据用户组是否有上下级关系,可以分为有上下级的用户组和普通用户组:

  1. 具有上下级关系的用户组: 最典型的例子就是组织和职位
  2. 普通用户组: 即没有上下级关系,和组织架构,职位都没有关系。也就是说可以跨部门,跨职位。我们可以设置一个拼团用户组,该组可以包括研发部的后台开发人员,运营部的运营人员,采购部的人员等等。

组织

把组织与角色进行关联,用户加入组织后,就会自动获得该组织的全部角色,无须管理员手动授予

职位

每个组织部门下都会有多个职位,比如财务部有总监,会计,出纳等职位,虽然都在同一部门,但是每个职位的权限是不同的。职位高的拥有更多的权限。一个人可能身兼多职

含有组织/职位/用户组的模型

授权流程

  1. 手动授权: 管理员登录权限中心为用户授权,根据在哪个页面授权分为两种方式:给用户添加角色,给角色添加用户。给用户添加角色就是在用户管理页面;给角色添加用户就是在角色管理页面,实现了给批量用户授予角色的目的。
  2. 审批授权: 即用户申请某个职位角色,那么用户通过OA流程申请该角色,然后由上级审批。

表结构

根据这个表结构,我们可以看到,一个完整的 RBAC3 模型,用户可以绑定三个关联:

  1. 用户 - 组织 - 权限关联
  2. 用户 - 身份 - 权限关联
  3. 用户 - 用户组 - 权限关联

解决方案

RBAC 解决方案,主要分为两部分

权限控制

主要是为相关 API 添加权限相关的代码。权限控制一般分为以下几种情况:

  1. URL鉴权
  2. API鉴权(主要是系统间的调用)
  3. 前端模板控制(根据权限渲染不同的前端界面)
  4. 菜单树控制(根据权限生成页面的树状结构)
  5. SQL查询(行/列 级权限)

权限管理

约70%的工作量,处理权限的分配、管理问题。目前常用的权限分配有以下几种:

  1. 手动授权(管理后台手动授予某人某角色,或进行摘除)
  2. 动态组授权(通过 人/部门/职级/岗位/员工类型/岗位 等数十种条件自由组合,根据员工入转调离的动作,自动进行授权)
  3. API授权(通过API进行角色的授予,摘除)
  4. 审批流授权

操作系统(Linux 为例)

Linux 操作系统,没有组织架构等维度,所以权限设计相对比较简单。

在linux中一切都是文件(文件夹和硬件外设是特殊的文件)

由于一切皆为文件。所以Linux 引入了2个文件来管理用户(组), /etc/passwd 存放用户,/etc/group 存放组, 然后在文件系统中的每个文件的文件头里面添加了用户和文件之间的关系信息。

  1. 用户和文件的关系只有2种, 拥有和不拥有。
  2. 组和文件的关系只有2种,拥有和不拥有
  3. 用户和组的关系只有2种, 属于和不属于

将这三种关系叠加,用户和文件的最终关系可以归纳为3类:

  1. 用户拥有该文件
  2. 用户属于某个组, 某个组拥有该文件(即用户通过属于某组来拥有该文件)
  3. 用户不拥有该文件

在文件的文件头里,则存储了3组信息分别对应上面3类关系

  1. 第一组存放拥有该文件的用户的的权限
  2. 第二组存放拥有该文件的组的权限,(所有属于该组的所有成员都获得此权限)
  3. 第三组存放所有不拥有该文件的用户(等于所有用户减去以上2类用户)所获得权限。

权限一共有三种读(缩写为r),写(缩写为w),执行(缩写为x)

下面是一个例子

显示readme.txt的权限信息

r-x-w-rw- tom admin readme.txt

上面的 r-x-w-rw-,每3个字符为一组,分别对应用户,组,其他用户,- 表示无此权限

  1. 用户(缩写为u)的权限:是读(r)和执行(x)
  2. 组(缩写为g)的权限:是写(w)
  3. 其他用户(缩写为o)的权限:是读(r)和写(w)

用户tom 拥有该文件。组admin拥有该文件

在实际的应用当中, 我们一般会用应用程序的名字来设置组名

比如在我的系统中就有mysql组,mongdb组

参考