一、权限模型设计:从RBAC到ABAC,再到多租户下的权限粒度
权限模型这件事,说白了就是解决「谁能做什么」的问题。我做了这么多年权限系统,踩过的坑比走过的路还多。今天咱们就聊聊RBAC和ABAC这两个主流模型,以及多租户场景下怎么划分权限粒度。
1.1 RBAC原理:角色是权限的集合
RBAC,全称Role-Based Access Control。核心思路就是把权限打包成角色,然后把人塞进角色里。你想想看,这样就不用给每个用户单独配权限了,省事不少。
我在项目中遇到过最典型的RBAC场景就是企业办公系统。管理员、经理、普通员工,三种角色搞定所有。系统里几百号人,权限管理却只需要维护三套角色配置——这就是RBAC的魅力。
RBAC的核心概念
- 主体(Subject):用户或用户组
- 角色(Role):权限的逻辑集合
- 权限(Permission):对资源的操作许可
- 会话(Session):主体激活的角色集合
RBAC0是最基础的模型,只有用户-角色-权限三层。我记得有个项目,需求方非要加角色继承和角色约束,那就是RBAC1和RBAC2的事了。不过说实话,80%的场景用RBAC0就够了,别给自己找不痛快。
实战小建议
我一般会先画一个「主体-角色-权限」的关系表。角色别超过20个,太多就说明你的角色粒度有问题了。
1.2 ABAC原理:属性驱动的动态决策
ABAC(Attribute-Based Access Control)比RBAC灵活得多。它不靠角色,而是根据一堆属性来算你有没有权限。属性可以是用户的、资源的、环境的,甚至是上下文相关的。
举个例子:
「允许深圳分公司的工程师在工作日9:00-18:00访问销售数据,但只有销售额超过10万的客户记录才可见。」
这种场景RBAC就不好使了。你总不能为了「深圳+工程师+工作日+9-18点+销售额>10万」建一个角色吧?那角色表得炸了。
我曾经犯过的错
有一次我把ABAC的决策逻辑写死在代码里,结果业务部门三天改一次规则,每次都要改代码重新部署。后来我学乖了,把规则存到数据库里,用表达式引擎动态解析。你猜怎么着?运维同事再也不用半夜被我叫起来上线了。
| 对比维度 | RBAC | ABAC |
|---|---|---|
| 决策依据 | 角色 | 属性组合 |
| 灵活性 | 中 | 高 |
| 维护成本 | 低 | 中高 |
| 性能 | 高(缓存友好) | 中(需实时计算) |
| 适用场景 | 稳定、角色分明 | 动态、条件复杂 |
我个人的习惯是:能用RBAC解决就别上ABAC。ABAC虽然灵活,但规则多了容易变成一团乱麻。你想想看,几百条属性规则相互影响,排查问题时脑袋都要大了。
1.3 多租户下的权限粒度划分
多租户场景有个特殊问题:权限不仅要管「谁能做什么」,还得管「在哪个租户里做」。这就涉及到权限粒度的划分了。
我记得有个SaaS项目,刚开始只分了三个粒度:系统级、租户级、用户级。结果客户越来越多,需求越来越怪。有的租户要限制某个数据表里的行级访问,有的要控制API的调用次数,有的甚至要精细到某个字段的可见性。
1.3.1 四个粒度层级
- 租户级粒度:整个租户的开关。比如租户A能不能使用导出功能。
- 模块级粒度:功能模块的访问。比如租户A的销售模块对哪些人开放。
- 数据级粒度:具体数据行/对象的访问。比如只允许查看自己团队的客户。
- 字段级粒度:数据字段的可见性。比如销售金额字段只对经理可见。
我建议的粒度划分原则
- 静态权限用RBAC,动态条件用ABAC
- 租户级和模块级用RBAC
- 数据级和字段级用ABAC
- 不要一开始就追求太细的粒度,迭代着来
1.3.2 多租户下的权限决策流程
实际执行时,我会把权限决策拆成三步:
第一步:租户身份校验
先确认请求属于哪个租户,有没有被冻结或过期。
第二步:模块级RBAC检查
用户角色有没有这个模块的访问权限?没有就直接拒绝了。
第三步:数据级/字段级ABAC过滤
通过了前两步,再根据属性规则做精细化控制。
避坑提示
我曾经遇到过一个项目,在数据级权限上用了全表扫描过滤,结果一个查询跑了十几秒。后来老老实实加了索引和缓存,还在SQL层面就做了权限约束。嗯,这里要注意——权限过滤尽量前置到数据库查询里,别在应用层一条条过滤。
1.4 综合推荐:混合模型
讲了这么多,你可能会问:到底用RBAC还是ABAC?我的答案是——都用。
实际操作中,我推荐一种混合模型:
- 底层权限(租户、模块):用RBAC,简单高效
- 上层权限(数据、字段):用ABAC,灵活精确
- 中间加一层缓存:把ABAC计算结果缓存起来,避免每次请求都重新算
这样既能享受RBAC的简洁,又能用ABAC处理复杂场景。我记得有个项目用这套方案扛住了上万条策略规则,线上运行两年没出过权限相关的事故。
最后一句掏心窝的话
权限模型没有银弹。开始做之前,先问问自己:这个系统未来三年会不会有复杂的权限需求?如果大概率没有,RBAC就够了。如果可能很复杂——比如多租户SaaS——那趁早把ABAC的架子搭好。别等到客户来投诉了才临时抱佛脚。