先搞明白:RBAC 到底是个啥?
动手设计之前,得先把 RBAC 的本质聊清楚。我见过不少团队,一上来就是“我们要上 RBAC”,可真问他们 RBAC 是什么、能解决什么问题,反而支支吾吾说不明白。
说白了,RBAC(Role-Based Access Control,基于角色的访问控制)就一句话:把权限绑在角色上,把角色分给用户。
传统做法是直接把权限给用户。一个人有 50 个权限,公司 1000 号人,权限管理就是 50000 条关系;哪天入职个新人或走个老人,运维同学得手动改半天。
RBAC 的思路正好反过来:权限不直接给用户,先给角色,再把角色给用户。比如“运营”这个角色,能看数据、改活动、回复评论。新来一个运营同学,直接给他“运营”角色,权限就齐了;人走了,把角色一删,权限也清干净了。
这是 RBAC 最基础、也最核心的思想,听起来简单到爆对吧?但就是这么简单的东西,真正落地的时候,坑能让你哭出声。
我后来仔细翻了 NIST(美国国家标准与技术研究院)的 RBAC 标准,才发现这个模型其实有 4 个层级:
- 核心 RBAC:最基础的用户-角色-权限三件套
- 分层 RBAC:角色可以继承,子公司自动拥有母公司的权限
- 约束 RBAC:加入职责分离,比如申请报销的人不能同时是审批人
- 对称 RBAC:能在企业层面查看所有权限的分布情况
血泪教训:权限系统的 4 个常见大坑
第一个坑:角色爆炸
之前的系统里,角色多到像“俄罗斯套娃”。光“运营”这一个角色,就拆成了“初级运营”“中级运营”“高级运营”“运营主管”“运营经理”,每个角色的权限只差一两个点。
为什么会这样?因为每次业务方提需求,开发同学图省事,就新建一个角色,觉得这样最安全。结果角色越加越多,最后连产品经理自己都搞不清这 80 多个角色到底是干什么的。
第二个坑:权限继承套娃
做子公司系统时,设计同学觉得“子公司管理员”应该自动拥有“普通管理员”的所有权限,就配了继承关系。后来又加“区域子公司管理员”,继续继承“子公司管理员”,再继承“普通管理员”。
看着挺合理对吧?结果某次审计发现,一个“区域子公司管理员”居然能直接看到全集团的数据——因为继承链太深,某个祖辈角色的权限没清理干净,一直漏到了最下面。
第三个坑:数据权限和功能权限混着搞
这个坑最隐蔽。功能权限管的是“能不能做这个操作”,数据权限管的是“能看到哪些数据”。举个例子:客服能看订单,这是功能权限;但客服只能看自己负责店铺的订单,这是数据权限。
之前的系统里,这俩混在一个权限点里。某次改版时把客服的“查看订单”权限关了,结果客服连登录都登不上;或者数据范围配错,A 店的客服能看到 B 店的数据。这种问题排查起来能把人逼疯。
第四个坑:权限清理没人管
这个最致命。之前的权限系统,从上线到崩的 3 年里,从来没做过权限审计。用户离职不删角色,业务下线不删权限,部门调整不更新角色。
3 年下来,权限表里堆满僵尸数据。很多老员工离职时,IT 只是直接禁账号,但角色还在、权限还在;新员工来了,复制老员工的角色模板,历史遗留的权限就这么一代代传下去。
权限设计的第一步:搞清楚“谁”能“做什么”

聊 RBAC 设计之前,得先明确一个前提:不是所有系统都适合用 RBAC。
如果系统就三、五个人用,权限点只有十来个,那别上 RBAC,搞个简单的权限开关就够了。RBAC 适合的场景是:用户多(几百以上)、权限点多(几十个以上)、角色清晰(能按职能划分)。
判断清楚之后,我们来看看 RBAC 的“五要素”,这比网上常说的“三要素”更完整:
- 用户(User):系统使用者,可以是人,也可以是系统/服务账号
- 角色(Role):一个或多个权限的集合,对应某种职能或岗位
- 权限(Permission):对某个资源能做的某个操作,比如“删除订单”
- 资源(Resource):权限作用的对象,比如订单、用户、商品
- 会话(Session):用户登录后产生的上下文,决定这次请求使用什么角色
“资源”这个点经常被忽略。设计 RBAC 时,只考虑“功能权限”、不考虑“数据权限”,后面大概率要返工。实际上,功能权限决定了“能不能做”,数据权限决定了“能在多大范围内做”。
举个栗子:客服 A 和客服 B 都有“查看订单”的功能权限,但 A 只能看华东区的订单,B 只能看华南区的订单,这就是数据权限的差异。
一个好的权限模型,必须同时支持功能权限和数据权限,而且要把它们分开配置。数据范围作为角色的一个属性,可以配置成“全部数据”“本部门数据”“本人数据”等。
角色怎么设计?这 5 个原则能救你
角色是 RBAC 的核心,也是最容易出问题的地方。角色设计得好,权限管理就清晰;设计得烂,后面就是无底洞。
按这套原则执行下来,2 年时间,角色数量从 80 多个压缩到 25 个,权限点从 200 多个清理到 120 个,权限问题直接减少了 70%。
原则一:按“职能”设计角色,别按“人”设计
很多团队设计角色时按“人”来:“小张是运营,给他建个运营角色”;“李四是主管,再建个运营主管角色”。这样角色一定会爆炸。
正确做法是按“职能”来。运营是职能,不管谁来做运营,都用“运营”这个角色;运营主管也是职能,不管谁当主管,都用“运营主管”这个角色。
如果运营里有人权限多一点、有人少一点怎么办?通过“数据权限”区分,而不是新建角色。
原则二:角色数量控制在 30 个以内
经验告诉我,超过 30 个角色,团队就管不过来了。角色多到一定程度,每个角色对应的用户会很少,“僵尸角色”也会越来越多。
压缩角色的标准:一个角色的用户数少于 5 个,就要考虑合并。
原则三:角色继承最多 2 层
2 层是最平衡的选择——既保留继承的便利,又不会让继承链失控。
1 层不够灵活(所有角色都独立,配置工作量大),3 层又太容易出问题(权限漏下去都不知道从哪儿漏的)。
原则四:禁止给单个用户单独配置权限
很多团队图省事,会出现这种情况:“大部分运营都有 A 权限,但小张没有,给他单独去掉”。时间一长,权限配置就变成“角色权限 + 用户特例”的大杂烩,根本没人能说清每个人到底有哪些权限。
正确做法是:要么给小张换角色,要么新增一个角色,要么调整角色权限。绝不允许在用户级别单独配置权限。
原则五:超级管理员只能有一个
很多系统里都有“超级管理员”这个角色,但一不小心就会有 N 个人拥有。
规定:超级管理员账号只能有 1 个,而且必须经过 2 人审批才能登录。为什么?因为超级管理员权限太大,一旦被滥用或者被盗,影响是灾难性的。
权限点怎么拆?这 3 个粒度要选对
权限点拆得对不对,决定了权限系统好不好用。太粗,管不住;太细,配置工作量爆炸。
业务动作粒度
权限点应该对应“业务动作”,而不是“技术操作”。比如“退款”是业务动作,对应一个权限点;“调用退款 API”是技术操作,不应该作为权限点。
订单模块的权限点参考:
- 查看订单列表
- 查看订单详情
- 修改订单金额
- 申请退款
- 审批退款
- 关闭订单
- 导出订单数据
看着挺多,但一个角色顶多配十来个权限点,不会太复杂。
操作和资源分离
权限点应该设计成“操作 + 资源”的形式,比如“查看订单” = 操作(查看) + 资源(订单)。好处有两个:
一是配置灵活,比如“运营”角色有“查看订单”“修改订单”权限,但没有“删除订单”权限。二是扩展方便,以后加个“商品”资源,直接复用“查看”“修改”“删除”这些操作就行。
避免权限点冗余
“运营”有“查看订单”权限,“运营主管”也有。如果“运营主管”是继承自“运营”的,那“运营主管”就不用再勾选“查看订单”,否则就是冗余。
冗余的权限点配置看起来不影响功能,但时间一长,根本不知道哪个权限是继承来的、哪个是单独配的。审计权限的时候,能把你累死。
角色继承怎么做?这套方法能让你少踩 80% 的坑
角色继承是个好东西,用对了能省一半的配置工作;用错了,就是继承套娃。
只在“明确的层级关系”中使用继承。比如:
- 总经理 → 副总经理 → 部门经理 → 普通员工
- 集团管理员 → 子公司管理员 → 部门管理员
- 超级管理员 → 系统管理员
这种自上而下、严格的层级关系,适合用继承。
但像“运营”和“客服”,这俩是平级职能,不是层级关系,就不适合用继承。它们之间如果有共性权限(比如都能看用户信息),应该抽出一个“基础员工”角色,让“运营”和“客服”都继承它。
父角色要稳定
父角色是基础,它的权限变动会影响所有子角色。所以父角色的权限一定要“稳定”,别三天两头改。父角色权限修改需要走 2 级审批,防止有人乱动。
子角色可以“减权限”,不能“加权限”
子角色继承父角色的所有权限后,可以减掉自己不需要的权限,但不能加父角色没有的权限。
如果子角色能随便加权限,那“总经理”继承“普通员工”之后,再加个“看工资”权限,结果“普通员工”通过反向继承也能看工资,那就乱套了。
禁止双向继承
A 继承 B,B 继承 A,这种循环继承绝对禁止。技术上可能能配出来,但维护起来就是灾难。定期跑个脚本查一下有没有循环继承,是个好习惯。
数据权限和功能权限必须分开
数据权限和功能权限,必须分开配置、分开校验。
分开配置:角色配置时,要能分别配置“功能权限”和“数据范围”。比如“客服”角色,功能权限是“查看订单”,数据范围是“本部门数据”。
分开校验:每次请求不仅要校验功能权限(有没有“查看订单”的权限),还要校验数据权限(这个订单是不是本部门的)。
数据范围做成了 5 种标准类型:
- 全部数据:能看到所有数据,一般只有超级管理员有
- 本部门数据:只能看本部门的数据
- 本部门及子部门数据:看本部门和下级部门的数据
- 本人数据:只能看自己创建或负责的数据
- 自定义数据:可以配置具体能看到哪些数据(高级用法,一般很少用)
这 5 种类型能覆盖 90% 的业务场景。复杂的数据权限需求(比如“华东区大客户的数据”),单独抽出一个“数据范围模板”来配置,避免角色配置时过于复杂。
数据权限的校验,要放在业务逻辑的最前面。一些系统把数据权限校验放在 Controller 层,结果 Service 层的方法被别的服务一调,权限就漏了。数据权限必须下沉到 Service 层,甚至 DAO 层。
权限系统怎么落地?这套流程能直接抄
第一步:权限梳理(2 周)
把现有权限全部列出来,包括:
- 系统里有哪些模块(订单、商品、用户、活动等)
- 每个模块有哪些操作(增删改查、审核、导出等)
- 现在有哪些角色,每个角色有哪些权限
- 每个用户有哪些角色
这一步最痛苦,因为权限表往往是乱的,很多权限没人说得清是怎么来的。全量导出 + 业务方确认 + 技术校验。业务方确认每个权限是不是还在用,技术校验每个权限点是不是有代码在用。
第二步:模型设计(1 周)
根据梳理结果,设计新的权限模型。包括:
- 角色列表(精简后)
- 权限点列表(标准化后)
- 角色和权限的对应关系
- 角色继承关系
- 数据范围类型
这一步要画清楚 ER 图,写清楚权限矩阵,让所有相关方评审通过。
第三步:系统开发(3 周)
开发新的权限系统,包括:
- 权限管理后台(角色、权限、用户关系配置)
- 权限校验中间件(统一处理功能权限和数据权限)
- 权限数据迁移工具(把老数据迁到新系统)
- 权限审计日志(记录所有权限变更和权限使用情况)
第四步:数据迁移(1 周)
这一步最容易出问题,因为老数据往往是乱的。迁移时要“双写 + 对比”:老系统和新系统同时写入,然后定期对比数据是否一致。等对比一致率超过 99.9% 后,再切换流量。
第五步:灰度上线(2 周)
不要一次性全量切换。先切 10% 的用户,观察 3 天;没问题切到 50%,再观察 3 天;最后切到 100%。切换过程中,实时监控权限相关报错和工单。
第六步:权限清理(持续)
上线不是结束,是开始。要建立定期清理机制:
- 每月清理一次离职员工的角色
- 每季度清理一次僵尸角色(用户数少于 5 个的角色)
- 每年做一次全面的权限审计
那些能让你少走弯路的工具和框架
Casbin:权限校验的瑞士军刀
Casbin 是开源的权限框架,支持 RBAC、ABAC 等多种模型,还支持 Go、Java、Node、Python 等多种语言。
用 Casbin 做权限校验中间件,配置一个策略文件,就能搞定大部分场景:
[role_definition]
g = _, _
[policy_definition]
p = sub, obj, act
[role_assignment]
g, alice, admin
g, bob, user
[policy]
p, admin, order, delete
p, user, order, read
Casbin 的好处是模型和代码分离,权限策略改了不用发版,刷新策略文件就行。对于权限经常变动的系统,这点特别重要。
Spring Security(Java 生态)
Java 生态基本是必选。它把认证、授权、攻击防护这些都封装好了,注解式的权限控制用起来很爽:
@PreAuthorize("hasRole('ADMIN') and hasAuthority('order:delete')")
public void deleteOrder(Long orderId) {
// 删除订单逻辑
}
自研权限管理后台
不管用哪个框架,权限管理后台都要自研,因为通用框架的管理后台满足不了业务需求。
自研的管理后台,包含这些功能:
- 角色管理(增删改查、权限配置、用户分配)
- 权限管理(权限点列表、权限点分组)
- 用户管理(用户列表、角色分配)
- 权限审计(权限变更记录、权限使用日志)
- 数据迁移(老数据导入导出)
管理后台的操作要全部记录日志,日志要包含“谁、什么时候、改了什么、为什么改”。出问题能追溯,审计时有依据。
避坑清单:这 10 件事千万别做
- 不要直接把权限赋给用户,哪怕只是临时测试
- 不要搞超过 3 层的角色继承,2 层就够了
- 不要把数据权限和功能权限混在一起配置
- 不要在代码里硬编码权限判断
- 不要忘了离职员工的角色清理,至少每月一次
- 不要让超级管理员有多个,必须限制在 1 个
- 不要省略权限审计环节,上生产前必须做权限审计
- 不要全量上线,必须灰度,出了问题能回滚
- 不要忽视权限相关的日志,权限变更和使用必须留痕
- 不要一个人决定权限设计,必须多角色评审(产品、技术、安全、业务)
写在最后
权限系统这东西,平时没感觉,出问题就是大问题。轻则用户投诉,重则数据泄露,每一次都是血泪教训。
做完那次权限系统重做之后,我最大的感受是:权限设计不是技术问题,是业务问题。你必须深入理解业务,才能设计出既安全又好用的角色和权限。不懂业务的纯技术人员,设计出来的权限系统一定不接地气。
我后来带新人的时候,都会跟他们说:做权限系统之前,先去业务一线待两周,搞清楚每个岗位每天都在干啥,他们需要看什么、改什么、审核什么。带着这个理解去做设计,才能做出真正能落地的系统。