常见的权限模型
权限模型用于管理和控制用户对系统资源的访问权限。
常见的权限模型:
- RBAC (Role-Based Access Control, 基于角色):将权限关联到角色上,然后将用户关联到角色上来获得权限
- ABAC (Attribute-Based , 基于属性):使用属性(例如用户属性、资源属性、环境属性等)来决定用户对资源的权限,依赖于属性的匹配规则
- DAC (Discretionary ~, 自主):资源的所有者可以自行决定其他用户对该资源的访问权限
- MAC (Mandatory ~, 强制):由系统管理员通过标签或者级别来控制资源的访问,适用于需要高度安全的环境,如军事和政府系统
- PBAC (Policy-Based ~, 基于策略):相比于 ABAC,PBAC 使用的策略和条件更加复杂
ABAC 直接通过属性来确定权限,更加精细和灵活,但是实现起来更复杂;RABC 更简单,但是因为权限依赖于独立的角色模型,所以灵活性差一点。
综上,对于中小型项目,RABC 是性价比最高的选择。
RBAC 模型
RBAC 中涉及到三个关键概念:
- 权限:对模型或者资源的操作,可以与页面上的按钮一一对应
- 角色:一组权限的集合,角色之间还可以分级、组合、继承
- 用户:用户通过关联角色来获取对资源的控制权限
权限设计的一个例子:
- 在模型层面我们可以设置:
- 创建实例:不涉及具体的实例权限
- 查看实例:在模型层面上允许查看实例意味着可以读取该模型的所有实例,此时将忽略实例层面上的权限控制
- 修改实例:在模型层面上允许修改实例意味着可以修改该模型的所有实例,此时将忽略实例层面上的权限控制
- 删除实例:在模型层面上允许删除实例意味着可以删除该模型的所有实例,此时将忽略实例层面上的权限控制
- ……
- 在实例层面上我们单独控制对具体实例的权限:
- 查看实例:是否允许查看当前实例
- 修改实例:是否允许查看修改实例
- 删除实例:是否允许查看删除实例
- 运行任务:是否允许基于本实例投递任务
- ……
在涉及到对分层资源的控制时,需要将权限也设计成对应的树形结构,整理出对应的权限树。
带分级的 RBAC 模型
角色区分上下级,上级角色继承下级角色的所有权限,并且还可以添加额外的权限。
上下级之间一般存在两种对应关系:
- 一个下级只有一个上级,一个上级可以有多个下级:这种比较常见
- 一个下级可以有多个上级:这种比较少见
带约束的 RBAC 模型
- 角色互斥:一个用户不能同时关联两个角色,例如一个员工不可能既是会计又是审核
- 数量约束:约束角色关联的用户数量,或者约束用户关联的角色数量,例如超级管理员角色只能关联一个用户
- 先决条件:在分级角色中,用户想要关联一个上级角色之前,必须要先关联其下级角色
用户组
当给某部门下大量用户批量关联新角色时,我们需要手动给每一个用户关联这个角色。
此时可以引入 用户组 的概念:将这些用户添加到某个用户组,然后将角色关联到用户组上,该用户组内的所有用户即可获取该角色的权限。
注意,用户组并没有完全隔断用户和角色的关联,它们的关系如下:
用户可以通过用户组关联角色,也可以直接关联角色。
组织架构
组织架构一般指的是部门的层级关系,跟人员的上下级有区别。
例如研发部是一个部门,它下面还可以包含产品中心和研发中心两个部门。
在每个部门内部存在很多人员,这些人员之间也存在上下级关系。
上级部门中的人员与下级部门的人员不存在必然的上下级关系。
可以给部门关联角色,这样新加入部门的用户将自动继承该部门关联的角色。
部门关联的角色只涉及基础权限,即部门内大家共有的权限。
好处:
- 新加入的用户可以直接继承部门的基础权限,不需要重新分配权限
- 用户组织关系转移时权限会跟着部门自动调整,不再需要重新分配权限
职位
职位也是组织架构的一部分,其在 RBAC 模型中的位置与部门类似。
理想的 RBAC 模型
我们可以设计一个包含上面各种情况的模型,这个模型能解决大多数权限控制的问题,但是实现起来也较为复杂,注意具体情况具体分析。
- 角色和权限一般是多对多的关系:一个角色可以拥有多个权限,一个权限可以属于多个角色
- 用户组和权限一般是多对多的关系:一个用户组可以拥有多个权限,一个权限可以属于多个用户组
- 用户和用户组是多对多的关系:一个用户组可以包含多个用户,一个用户可以属于多个用户组
- 部门组织一般只关联基础权限,一般设计为一对一即可,可以为部门创建一个专属角色
- 职位和角色一般设计成多对多的关系,职位在继承部门的基本权限的基础上还可以附加额外的角色
- 用户和职位一般是一对一,也可能出现一个用户兼任多值的情况(一对多),具体分析
- 部门和职位一般也是一对多:一个部门拥有多个职位,一个职位必定只属于某个部门
- 用户在继承用户组、组织、职位的权限基础上,还可以附加额外的角色
权限数据表设计
以理想的 RBAC 模型为例,涉及到的实体有权限、角色、用户组、用户、部门组织、职位。
在 ORM 设计中,我们只需要关注实体表以及实体间的关联关系,框架会自己处理关联数据表。
UserGroup }o--|{ User : "" %% 用户组拥有的用户≥1,用户所属的用户组≥0
Department }|--|{ User : "" %% 部门拥有的用户≥1,用户所属的部门≥1
User ||--|{ Position : "" %% 用户拥有的职位≥1,职位所属的用户==1
Department ||--|{ Position : "" %% 部门拥有的职位≥1,职位所属的部门==1
UserGroup }o--o{ Role : "" %% 用户组拥有的角色≥0,角色所属的用户组≥0
User }o--o{ Role : "" %% 用户拥有的角色≥0,角色所属的用户≥0
Department }o--o{ Role : "" %% 部门拥有的角色≥0,角色所属的部门≥0
Position }o--o{ Role : "" %% 职位拥有的角色≥0,角色所属的职位≥0
Role }o--o{ Permission : "" %% 角色拥有的权限≥0,权限所属的角色≥0
Role ||--o{ RoleMut : "" %% 角色拥有的互斥关系≥0,一个互斥关系所属的角色==1
权限
权限名称通常指的是“在什么资源上施加什么操作”。
权限表的权限类型可以划分为:
- 系统管理:偏底层结构数据的管理,例如用户管理、角色管理、权限管理等
- 内容管理:与内容相关的权限,例如创建、编辑和删除内容的权限
- 数据管理:与数据相关的权限,例如数据库访问、数据的导入和导出等
- 订单管理:与订单相关的权限,例如创建、编辑和删除订单的权限
- 财务管理:与财务相关的权限,例如支付管理、生成报表等
通过指定父权限的 ID,实现对权限的层次化管理,即权限树。
mermaid 语法参考:https://mermaid.js.org/syntax/entityRelationshipDiagram.html
评论区