传统 RBAC(Role-Based Access Control)模型在企业系统中被广泛应用,但在复杂业务场景下容易出现 「角色爆炸」 问题。本文在经典 RBAC 的基础上,引入 用户级 Allow / Deny 覆盖机制,并结合 Bitmask 位掩码 优化权限存储与鉴权性能,实现 API 级细粒度控制,满足多业务线、复杂授权场景下的权限管理需求。
RBAC 权限模型简介#
RBAC(Role-Based Access Control,基于角色的访问控制)是一种通过 「角色」 来组织和管理权限的访问控制模型。其核心思想是:用户不直接拥有权限,而是通过角色间接获得权限。
这种设计将「用户」和「权限」解耦,大幅提升了权限管理的可维护性。
核心组成#
典型 RBAC 模型包含以下几个核心概念:
- User(用户) :系统的使用者,如管理员、员工、主管等;
- Role(角色) :权限的集合,是权限的载体;
- Permission(权限) :系统允许执行的具体操作(如访问某个 API、执行某个按钮操作等)。
数据库模型设计#
标准 RBAC 的数据库模型通常包括:
user表role表permission表user_role表(用户与角色,多对多)role_permission表(角色与权限,多对多)
关系结构如下:
User <---> User_Role <---> Role <---> Role_Permission <---> Permissionplaintext优缺点#
RBAC 模型的优点是权限分配清晰、管理结构规范,维护成本较低且用户与权限解耦
缺点是当某个用户需要「特殊权限」,需要给该用户单独新增一个角色,久而久之角色数量呈指数级增长,这就是所谓的 「角色爆炸」
优化方案设计#
为了解决角色爆炸问题,并提升权限系统性能,本文在 RBAC 基础上做了两点核心优化:
- 引入用户级 Allow / Deny 覆盖机制
- 使用 Bitmask 位掩码优化权限存储与鉴权计算
引入用户级 Allow / Deny 覆盖机制#
在保留原有 RBAC 模型的前提下,新增一张 user_permission 表,用于记录用户级别的权限覆盖。
该表支持两种类型:
- Allow(允许)
- Deny(拒绝)
当某个用户需要特殊权限时,无需新增角色,只需在 user_permission 表中新增一条记录,即可实现对角色权限的局部覆盖。
最终权限可通过以下规则计算:
最终权限 = (角色权限 ∪ 用户Allow) - 用户Denyplaintext这样既保留了 RBAC 的结构优势,又解决了「角色爆炸」问题。
使用 Bitmask 优化权限存储与鉴权性能#
在 API 级细粒度权限控制场景下,如果每个用户和 API、角色和 API 都单独存储一条权限数据,会产生庞大的数据量,为此,引入 Bitmask 进行优化。
将某个模块下的所有 API 权限映射为一个 64 位整数:
- 默认值为
0 - 每一位代表一个 API 权限
- 若允许访问,则将对应位置为
1
例如:
第 0 位 -> 查询接口
第 1 位 -> 新增接口
第 2 位 -> 删除接口
...plaintext一个角色或用户在某模块下的所有权限,仅需一个 BIGINT 字段存储,一行数据即可表示完整权限集合,大幅降低存储空间占用
在实际鉴权时流程如下:
- 从拦截器中获取当前 API 的 URL
- 解析其对应模块及位序号
- 计算用户最终权限掩码
finalMask= (roleMask | userAllowMask) & ~uerDenyMask - 判断对应位是否为
1
核心逻辑示例:
boolean hasPermission = (finalMask & (1L << apiIndex)) != 0;java整套鉴权逻辑仅通过位运算完成,无需多表 join,无需大量权限比对,时间复杂度接近 O(1)。
扩展:ABAC 权限模型#
ABAC(Attribute-Based Access Control,基于属性的访问控制)是一种基于 「属性 + 策略规则」 进行动态授权的权限模型。
其核心思想是:是否允许访问,取决于「你是谁 + 你在什么场景 + 访问什么资源 + 满足什么规则」。
ABAC 权限模型是一种更灵活、更细粒度、更动态的权限控制模型。
ABAC 的核心组成#
ABAC 的决策基于四类属性:
- 用户属性:描述访问者本身的属性;
- 资源属性:描述被访问对象的属性;
- 环境属性:描述当前访问环境,例如访问时间、IP 地址;
- 操作属性:描述执行的动作。
ABAC 的决策方式#
ABAC 的核心是用策略定义一组规则,当属性满足规则时才允许访问。
例如,允许访问的条件:
用户.department == 资源.department
AND
资源.level != "机密"
AND
当前时间 在 9:00 - 18:00java如果全部条件满足则允许访问,否则拒绝访问。
ABAC 的优缺点#
ABAC 具有极强的灵活性,支持数据级权限控制,支持上下文感知(IP/权限),天然适合多组织多租户系统,但是实现复杂、策略管理困难、性能压力较大、规则冲突处理复杂。