运维知识
悠悠
2026年8月16日

权限系统搞崩了 3 次,我把 RBAC 吃透了:一份能落地的权限设计指南

先搞明白: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

如果系统就 3、5 个人用,权限点就 10 来个,那别上 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"是技术操作,不应该作为权限点。

订单模块的权限点参考:

  • 查看订单列表
  • 查看订单详情
  • 修改订单金额
  • 申请退款
  • 审批退款
  • 关闭订单
  • 导出订单数据

看着挺多,但一个角色顶多配 10 来个权限点,不会太复杂。

操作和资源分离

权限点应该设计成"操作 + 资源"的形式,比如"查看订单" = 操作(查看) + 资源(订单)。好处有两个:

一个是配置灵活,比如"运营"角色有"查看订单"、"修改订单"权限,但没有"删除订单"权限。
另一个是扩展方便,以后加个"商品"资源,直接复用"查看"、"修改"、"删除"这些操作就行。

避免权限点冗余

"运营"有"查看订单"权限,"运营主管"也有"查看订单"权限。如果"运营主管"是继承自"运营"的,那"运营主管"就不用再勾"查看订单"了,否则就是冗余。

冗余的权限点配置看起来不影响功能,但时间一长,根本不知道哪个权限是继承来的、哪个是单独配的。审计权限的时候,能把你累死


角色继承怎么做?这套方法能让你少踩 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 个
  • 不要省略权限审计环节,上生产前必须做权限审计
  • 不要全量上线,必须灰度,出了问题能回滚
  • 不要忽视权限相关的日志,权限变更和使用必须留痕
  • 不要一个人决定权限设计,必须多角色评审(产品、技术、安全、业务)

写在最后

权限系统这东西,平时没感觉,出问题就是大问题。轻则用户投诉,重则数据泄露,每一次都是血泪教训。

做完那套权限系统的重做之后,我最大的感受是:权限设计不是技术问题,是业务问题。你必须深入理解业务,才能设计出既安全又好用的角色和权限。不懂业务的纯技术人员,设计出来的权限系统一定不接地气。

我后来带新人的时候,都会跟他们说:做权限系统之前,先去业务一线待两周,搞清楚每个岗位每天都在干啥,他们需要看什么、改什么、审核什么。带着这个理解去做设计,才能做出真正能落地的系统。

如果这篇文章对你有帮助,欢迎转发给你的同事、朋友。权限系统是每个技术团队都要面对的问题,多一个人看到,就少一个人踩坑。

如果想看更多运维、系统设计、SRE 相关的实战经验,可以关注我的公众号「耕云躬行录」,每周都会更新干活内容。

也可以逛逛我的个人博客「躬行笔记」,里面整理了更多技术文章和工具脚本,欢迎来撩。

我们下期见!

文章目录

博主介绍

热爱技术的云计算运维工程师,Python全栈工程师,分享开发经验与生活感悟。
欢迎关注我的微信公众号@运维躬行录,领取海量学习资料

微信二维码