3. 权限模型基础:RBAC 与 ABAC 详解及选型对比

聊权限模型,很多人一上来就跟我争论「到底 RBAC 好还是 ABAC 好」。其实这个问题本身就有问题。没有最好的模型,只有最合适的场景。我在企业做数据安全治理这些年,见过太多「拿着 RBAC 锤子看什么都是钉子」的案例,也见过被 ABAC 的灵活性反噬的项目。

这一章,咱们把两个主流模型掰开揉碎讲清楚。你听完就能自己判断:我的场景,到底该用哪个。

3.1 RBAC:基于角色的访问控制

RBAC 的核心思想很简单——用户不直接拥有权限,权限赋予角色,角色再赋予用户。说白了,就是加了一层「角色」做中间人。

核心三要素:

  • 用户(User):访问系统的自然人
  • 角色(Role):权限的集合,如「财务审核员」「数据管理员」
  • 权限(Permission):对资源的操作许可,如「读取客户表」「写入订单表」

我习惯把 RBAC 比作「门禁卡+楼层权限」:你拿到的工卡(角色)决定了你能进哪几层(权限)。换部门了?换张卡就行,不用重新配锁。

3.1.1 RBAC 的三种标准模型

模型 核心特征 适用场景
RBAC0 基础模型,用户-角色-权限三层 小型系统,角色固定
RBAC1 引入角色继承(上级角色自动拥有下级权限) 组织层级清晰的企业
RBAC2 引入约束(互斥角色、基数限制等) 合规要求严格的场景

嗯,这里要注意:RBAC1 的角色继承很容易被滥用。我曾经见过一个项目,角色层级叠了 7 层,最后没人说得清「高级运营经理」到底能看哪些数据。所以我的建议是——角色继承不要超过 3 层。

3.1.2 RBAC 的典型实现

-- 标准 RBAC 数据库表结构
CREATE TABLE users (
    user_id INT PRIMARY KEY,
    username VARCHAR(50)
);

CREATE TABLE roles (
    role_id INT PRIMARY KEY,
    role_name VARCHAR(50)
);

CREATE TABLE permissions (
    perm_id INT PRIMARY KEY,
    resource VARCHAR(100),
    action VARCHAR(20)  -- read, write, delete
);

-- 关联表
CREATE TABLE user_roles (
    user_id INT,
    role_id INT,
    PRIMARY KEY (user_id, role_id)
);

CREATE TABLE role_permissions (
    role_id INT,
    perm_id INT,
    PRIMARY KEY (role_id, perm_id)
);

你看,结构非常清晰。但实际项目中,我很少直接用这种「教科书式」的表结构。为什么?因为企业里的角色往往有几百个,权限条目上万条,纯靠 SQL 关联查询性能扛不住。我一般会在应用层做一层缓存,把「用户→权限」的映射提前算好。

避坑指南:我曾经在金融项目里遇到「角色爆炸」——每个业务线都要求独立角色,最后角色数量超过 500 个。解决方案是引入「角色组」概念,把相似角色归为一组,统一管理基础权限。

3.2 ABAC:基于属性的访问控制

ABAC 就灵活多了。它不看「你是谁」,而是看「你、资源、环境」这三者的属性组合。你想想看,RBAC 能处理「财务人员在工作时间之外不能导出报表」这种需求吗?不能。但 ABAC 可以。

ABAC 的决策公式可以概括为:

允许访问 = 用户属性 AND 资源属性 AND 环境属性 满足策略规则

3.2.1 四类核心属性

  • 用户属性:部门、职级、区域、入职时间
  • 资源属性:数据密级、所属部门、创建时间
  • 环境属性:访问时间、IP 段、设备类型
  • 操作属性:读取、写入、导出、打印

举个例子:

策略规则:
IF 用户.部门 = '财务部' 
   AND 资源.密级 = '内部' 
   AND 环境.时间 BETWEEN '09:00' AND '18:00'
   AND 操作 = '读取'
THEN 允许访问

这个策略,RBAC 得拆成多少个角色才能实现?我算过,至少 4 个。而 ABAC 一条规则搞定。

3.2.2 ABAC 的架构组件

ABAC 不是单机就能跑的,它需要一套完整的策略引擎。我画了一张图,帮你理解它的核心流程:

ABAC 策略决策流程 用户请求 策略执行点(PEP) 策略决策点(PDP) 属性源(PIP) 策略管理点(PAP) 目标资源 说明:PEP 拦截请求 → 向 PDP 发起决策 → PDP 从 PIP 获取属性、从 PAP 获取策略 → PDP 计算决策结果 → 返回 PEP → PEP 执行允许/拒绝 → 访问资源

这个流程里,最容易被忽视的是 PIP(属性源)。我见过太多项目,策略写得漂亮,但属性数据根本拿不到——用户部门信息在 HR 系统,资源密级在数据目录,环境信息在网络设备。属性源没打通,ABAC 就是空中楼阁。

注意:ABAC 的策略规则一旦超过 1000 条,性能就会急剧下降。每次请求都要实时计算属性组合,对 PDP 的算力要求很高。我建议在策略引擎前面加一层「策略缓存」,把高频决策结果缓存起来。

3.3 模型选型对比

好了,两个模型都讲完了。现在回到开头的问题:怎么选?

我个人的经验是——先看你的「权限维度」有多少。如果只有「部门+职级」两个维度,RBAC 完全够用。如果维度超过 5 个,或者有「时间」「地点」「设备」这类动态属性,ABAC 才是正解。

3.3.1 核心对比表

对比维度 RBAC ABAC
管理复杂度 低,角色定义清晰 高,策略规则维护成本大
灵活性 低,新增维度需新建角色 高,属性组合灵活
性能 高,预计算权限映射 中等,实时计算有开销
审计追溯 容易,角色即权限 较难,需记录属性上下文
实施成本 低,成熟方案多 高,需策略引擎和属性治理

3.3.2 我的选型建议

  • 选 RBAC 的场景:组织架构稳定、权限维度 ≤ 3、合规要求以「角色」为审计单元。比如内部 OA 系统、HR 系统。
  • 选 ABAC 的场景:权限维度多、有动态环境约束、数据密级分层复杂。比如跨部门数据共享平台、金融风控系统。
  • 混合模型:这是我在实际项目中最常用的方案。用 RBAC 做粗粒度权限(比如「谁能访问这个模块」),用 ABAC 做细粒度过滤(比如「谁能看到这条记录」)。

实战经验:我曾经帮一家银行做数据共享平台,最终方案是「RBAC 定范围 + ABAC 定条件」。用户先通过角色确定「能访问哪些表」,再通过属性策略确定「能看哪些行」。既保证了管理效率,又满足了监管对「最小权限」的要求。

嗯,最后说一句。模型选型不是一锤子买卖。我见过太多团队一开始选了 ABAC,结果半年后策略乱成一锅粥,又回退到 RBAC。所以我的建议是——从简单开始,逐步演进。先用 RBAC 跑起来,等发现「角色不够用」了,再引入 ABAC 做补充。别一开始就追求「完美模型」,那往往是灾难的开始。