2. 权限模型基础:RBAC、ABAC、PBAC 对比与选型
做权限设计,选对模型等于成功了一半。
我刚开始接触接口权限时,觉得能控制谁访问什么就够了。结果项目上线第三天,业务方就提了个需求:”运营部的小张能看到华南区的订单,但看不到华东区的。“ 嗯,这就是典型的模型没选好带来的麻烦。
这一章,我们直接把三种主流模型掰开来看。不是让你背定义,而是告诉你:
- 它们分别在什么场景下好用
- 我在实际项目中踩过哪些坑
- 怎么根据你的系统规模选型
2.1 RBAC:最经典的角色模型
RBAC(Role-Based Access Control),说白了就是”给角色授权,把人塞进角色“。
举个例子:
- 你定义一个”管理员“角色,拥有所有接口的访问权
- 再定义一个”访客“角色,只能看不能改
- 然后把用户 A 设置为管理员,用户 B 设置为访客
事情就这么简单。RBAC 的核心逻辑是:用户 → 角色 → 权限,中间加了一层角色做解耦。
适用场景:
- 组织结构稳定、岗位职责清晰的企业系统
- 用户量几万到几十万,角色不超过 20 个
- 权限粒度到模块/菜单级别就够用的场景
我在一家 SaaS 公司干过,他们用户角色只有 5 种:超级管理员、企业管理员、部门主管、普通员工、外部协作。用 RBAC 非常舒服,后端接口鉴权只需要查一次角色就行。
我个人习惯用 RBAC 作为权限系统的基础底座。即使后面要加 ABAC,也需要 RBAC 来兜底角色管理。
2.2 ABAC:灵活但复杂
ABAC(Attribute-Based Access Control),把权限的判断依据从”角色“变成了”属性“。
属性可以是:
- 用户属性:部门、职级、所在城市
- 资源属性:文档密级、数据所属区域
- 环境属性:访问时间、IP地址、设备类型
它的策略长这样:如果 user.department == "销售部" 且 resource.region == "华南" 且 time.hour >= 9 且 time.hour <= 18,则允许读。
| 维度 | RBAC | ABAC |
|---|---|---|
| 判断依据 | 角色 ID | 多属性组合 |
| 灵活性 | 低(需要新增角色) | 高(策略可动态组合) |
| 性能影响 | 几乎无 | 有(需要属性引擎计算) |
| 典型场景 | OA、后台管理 | CRM、金融、医疗 |
我曾经在一个项目里全盘采用 ABAC,结果策略规则膨胀到 2000 多条。每次请求都要做一次笛卡尔积式的属性匹配,接口响应时间从 20ms 飙到 300ms。嗯,后来我们做了策略缓存和预计算,才压回来。
所以我的建议是:能用 RBAC 解决的,别上 ABAC。
2.3 PBAC:面向策略的工程化方案
PBAC(Policy-Based Access Control),你可以理解成”把权限规则写成代码“。
它不绑定某个模型,而是提供一套规则引擎。常见的实现有:
- OPA(Open Policy Agent):CNCF 孵化的政策引擎
- Casbin:Go 语言写的访问控制框架
- 自定义 DSL:用 JSON 或 YAML 写策略
PBAC 的好处是:
- 策略可以热加载,不停机改权限
- 支持审计和模拟执行
- 一种策略统一管所有系统的权限
# Casbin 示例策略(model.conf)
[request_definition]
r = sub, obj, act
[policy_definition]
p = sub, obj, act
[matchers]
m = r.sub == p.sub && r.obj == p.obj && r.act == p.act
如果你所在的公司有统一的权限中台,或者微服务超过 10 个,我建议直接用 PBAC。不然每个服务自己写一套鉴权,维护成本会疯涨。
2.4 选型建议
说了这么多,到底怎么选?
我的经验是这样的:
- 80% 的场景,RBAC 就够用了。别为了“未来扩展”而上复杂的模型。未来到了再说。
- 如果有权限中台,选 PBAC。策略统一管理,比到处写 if-else 强一百倍。
- 如果确实需要按属性判断,比如“部门领导只能在上班时间看本部门的薪资数据”,那么 ABAC 是唯一的选择。但请做好性能压测。
我曾经见过一个团队,在用户量不到 3000 的创业项目里全盘上 ABAC + OPA。结果是架构复杂到没人敢改策略,半年后全部重写回 RBAC。你想想看,这中间浪费了多少时间?
所以我的建议很实在:从简单开始,按需进化。
2.5 小结
这一章我们做了三件事:
- 搞清楚了三种模型的核心差异
- 用表格和流程图展示了它们的适用边界
- 也分享了一些我亲身踩过的坑
选哪个模型,取决于你的系统规模和业务复杂度。没有银弹,只有权衡。