四、基于角色的访问控制(RBAC)

咱们这一章聊的是 RBAC,说白了就是解决一个核心问题:谁,能对什么,干什么。

我记得早期在做一个内部审计系统时,团队直接把权限写在用户表里,每个用户一行权限字段。一开始人少还好,等项目上线半年,光改权限就把测试组累趴下了。从那以后,我对 RBAC 模型就特别在意。

RBAC核心逻辑流程图 用户 (User) 分配 角色 (Role) 赋予 权限 (Permission) 控制 操作 + 对象 (读/写/执行) 会话 (Session) 约束 (Constraint) SSD / DSD / 角色基数 🛡️ 审计关注点 用户通过会话激活角色,角色聚合权限,权限最终映射到对象上的具体操作。 约束层是审计合规的关键——不冲突、不越权、不超量。

4.1 RBAC 模型

RBAC 的核心思想很简单:权限不直接挂用户身上,而是通过「角色」做中间层。用户和角色挂钩,角色和权限挂钩。这么做的好处,在实践中非常明显。

我接手过一个遗留系统,里面有 200 多个用户,每个人都是独立的权限列表。每次新人入职,运维就要照着 Excel 配一遍。说白了,这根本没法审计——你根本说不清谁到底能干什么。

引入 RBAC 之后,我们把权限收拢到 15 个角色里。审计起来特别清晰:谁是什么角色,角色有什么权限,一目了然。

RBAC 核心要素
  • 用户 (User) — 访问系统的主体,可以是一个人、一个服务账户。
  • 角色 (Role) — 权限的集合,代表一种工作职能。比如「审计管理员」、「财务审核员」。
  • 权限 (Permission) — 对某个资源的操作许可。常见形式:create:order、read:report。
  • 会话 (Session) — 用户登录后激活的角色映射,决定当前生效的权限范围。
  • 约束 (Constraint) — 防止滥用权限的规则,比如职责分离、角色互斥。

4.2 核心元素拆解

你想想看,RBAC 真正落地时,最让人头疼的不是模型本身,而是对「权限」粒度的把握。

我在项目中见过有人把所有增删改查按钮都做成独立权限,结果一个角色挂了四五十条权限,维护成本直接失控。后来我们定了一条铁律:权限必须按「资源 + 操作」来定义,不要拆到按钮级,除非审计有明确要求。

元素 定义 审计侧重点
用户 系统可识别的主体 用户归属部门、是否离职、是否存在共享账号
角色 权限的逻辑分组 角色定义是否合理、是否有人兼任互斥角色
权限 对特定资源的操作权 权限是否最小化、是否存在“影子权限”
会话 用户激活角色的通道 会话超时策略、多角色同时激活的合规性
约束 权限分配的规则边界 是否强制 SSD/DSD、是否有例外审批流程
避坑指南

我曾经在项目中踩过一个坑:角色命名太随意。运维建了个角色叫「role_A」,三个月后根本没人记得它是干嘛的。后来我们强制规定角色名必须包含业务域 + 职能,比如 finance_auditor、order_admin,审计合规一看就懂。

4.3 权限矩阵设计

权限矩阵,是 RBAC 落地的核心交付物。说白了,它就是一个二维表格:行是角色,列是资源/操作,交叉点打钩就表示有权限。

为什么要重视矩阵设计?因为审计时,第一个被翻出来的就是它。矩阵混乱,审计直接打回重做。

步骤 1:识别资源与操作

先把系统里的核心资源列出来。我习惯按模块分组,比如「订单管理」、「用户管理」、「报表中心」。每个资源对应的常见操作:查看、新增、编辑、删除、审批、导出。

步骤 2:定义角色

角色要对应实际岗位,比如:

  • 普通用户:只能看自己的数据。
  • 业务主管:可以看团队数据,能审批。
  • 系统管理员:能做配置更改,但不能看业务数据。
  • 审计员:只能读,不能写。

步骤 3:填充矩阵

把操作和角色交叉起来,只给真正需要的权限。这个环节特别容易出问题,很多人嫌麻烦,一口气给了一大片权限。嗯,这里要注意:矩阵上的每一个「√」都可能成为审计风险点。

角色 \ 操作 查看订单 创建订单 删除订单 审批订单 导出报表
普通用户 √(仅自己) √ — — —
业务主管 √(全团队) √ √ √ √
系统管理员 — — — — —
审计员 √(只读) — — — √
⚠️ 权限设计的红线

我曾经帮一家金融科技公司做审计复盘,发现他们的普通用户居然有「删除订单」的权限。原因是运维在做矩阵时复制粘贴漏改了。这个漏洞导致了一起严重的内部数据篡改事件。记住:矩阵里的每一个空格都必须是明确的「否」,不是忘了填。

4.4 约束机制:SSD 与 DSD

真正让 RBAC 从“可用”变成“审计合规”的关键,是约束。

  • 静态职责分离 (SSD):一个用户不能被同时赋予两个互斥角色。比如,不能同时是「财务审核员」和「财务记账员」。
  • 动态职责分离 (DSD):同一个会话中不能同时激活互斥角色。但用户可以在不同时间切换角色。

我个人的建议是:在金融、政务等强审计场景里,优先用 SSD,硬性不允许互斥角色共存。DSD 虽然灵活,但审计日志一旦查出来同一用户短期内切换互斥角色操作了同一笔数据,解释起来非常麻烦。

约束配置示例(伪代码)
// SSD 规则示例
constraint ssd_rules = {
  "role:finance_auditor" : ["role:finance_accountant", "role:payment_operator"],
  "role:order_admin"     : ["role:order_approver"]
}

// 角色基数限制
role_cardinality = {
  "role:system_admin" : { max_users: 2, description: "系统管理员最多2人" }
}
审计提示

约束规则不要写在代码里。我推荐用独立的策略引擎或配置文件管理,方便审计查阅和变更追踪。

4.5 从设计到落地的小结

RBAC 不是造个角色表就完事的。它需要你反复审视:角色是不是和业务对齐?权限是不是最小化?约束是不是真的被强制执行了?

我记得有一次,我们给一个客户做合规评估,对方的 RBAC 模型看起来挺完美,但实际跑一遍发现:约束规则只在 UI 上禁用按钮,后端 API 根本没验。那还叫什么审计控制?说白了,那就是个纸老虎。

所以我的原则是:矩阵设计要准,约束实现要狠,审计检查要勤。