企业后台权限模型设计:从角色到数据边界

权限模块很少在立项时被重视,却常在项目后期以事故的形式暴露。这篇文章把企业后台的权限拆成功能权限与数据权限两个层次,讲清楚 RBAC 的常见误用、数据权限的落地方式、多组织层级的处理,以及越权防护与权限审计该怎么做。

软件研发系统设计权限与安全
2026 年 9 月 15 日 · 广州科芃科技有限公司技术团队 · 全文约 3336 字

一、权限模型为什么总是在项目后期失控

权限模块几乎不会成为立项时的焦点。多数企业后台在需求阶段把注意力放在业务流程、报表和交互上,权限往往被压缩成一句「按角色控制」放在需求清单的末尾。等到系统上线、用户角色变多、组织架构调整、审计提出要求时,权限才第一次以「事故」的形式进入视野——某个人看到了不该看的数据、某个审批越过了层级、某个离职账号还留着入口。

这类问题的根源,通常不是写代码的人不小心,而是权限模型在一开始就没有被当成一个有独立设计对象的数据结构来对待。它被当成了散落在各个接口里的 if 判断,而不是一套可配置、可审计、可回溯的模型。

这篇文章讨论的是企业后台(管理端、运营端、监管端)的权限模型设计,重点在两个层次:一是我们熟悉的「功能权限」,即用户能不能进入某个菜单、调用某个接口;二是更容易被低估的「数据权限」,即用户能看到哪些范围的数据。二者合起来,才构成一个完整的权限边界。相关的分层设计思路可以参考 技术能力 与 工程与质量保障 中的说明。

二、RBAC 的基本结构与常见误用

RBAC(Role-Based Access Control,基于角色的访问控制)是企业后台里使用最广的权限模型。它的核心思想很朴素:不把权限直接授予用户,而是授予角色,用户通过角色获得权限。拆开看是四张表:

  • 用户(User):登录主体。
  • 角色(Role):一组权限的集合,代表一类职责。
  • 权限(Permission):对某个资源执行某个操作的许可,例如「订单-查看」「订单-导出」。
  • 关联关系:用户与角色多对多,角色与权限多对多。

这个结构本身没有问题,问题几乎都出在落地方式上。下面几种误用,在项目中出现的频率很高。

2.1 角色爆炸

最初角色只有三五个:管理员、运营、财务、客服。随着业务发展,每个部门都想有点自己的特殊权限,于是出现「运营-华东」「运营-华东-临时」「客服-主管」「客服-主管-带审核权」这样的角色,数量迅速膨胀到几十上百个。

角色爆炸带来的直接后果是维护困难:一个新功能上线,要判断给哪些角色加权限,没人说得清楚;一次组织调整,要改几十个角色,容易漏改。更深层的问题是,当角色数量增长到一定程度,它其实退化成了「一个角色对应一个人」,RBAC 的复用价值消失了。

缓解办法是区分两类角色:一类是职责角色,按岗位职责划分,数量有限且相对稳定;另一类是临时授权,用于处理短期、例外的情况,有明确的生效期与到期回收机制。不要把例外长期沉淀成新角色。

2.2 把岗位当成角色

岗位是组织管理上的概念,角色是权限上的概念,二者不总是一一对应。同是「区域经理」,负责不同区域、不同业务线时,需要的数据权限可能完全不同。如果把权限直接绑在岗位上,一旦组织调整,权限就得跟着大改。

更稳的做法是把「能做什么」和「能对谁做」拆开。角色描述「能做什么」(功能权限),数据的可见范围由独立的数据权限规则描述。这样组织调整时只改数据归属,不动角色定义。

2.3 把权限写死在代码里

另一种常见做法是在接口里直接判断用户身份,例如判断当前用户是否是某个固定账号、是否属于某个硬编码的部门。这种做法在项目初期很快,但在后期几乎无法维护:新增角色要改代码、发版,权限调整无法通过配置完成,也无法生成一份「谁有什么权限」的清单交给审计。

权限判断应当收敛到一个统一的鉴权层,接口只声明「需要什么权限」,由鉴权层决定「当前用户有没有」。这样权限的定义可以入库、可以配置、可以导出,也可以被审计。

三、从功能权限到数据权限

功能权限解决的是「能不能进这个页面、能不能调这个接口」,数据权限解决的是「进去之后能看到哪些行、哪些列」。很多系统的第一版只做了功能权限,等到业务方提出「不同区域的运营只能看自己区域的数据」时,才发现数据权限没有设计位置。

3.1 数据权限的四种常见形态

按可见范围的确定方式,数据权限大致可以分为四类:

  1. 本人数据:只能看到自己创建或负责的记录,例如客服看自己的工单。
  2. 本部门数据:能看到所属部门范围内的记录。
  3. 本部门及下级数据:沿组织树向下展开,例如区域经理看所辖门店。
  4. 自定义范围:由管理员显式指定可见的组织、区域或标签集合。

这四类往往需要在同一个系统里共存,而且要能按「角色 + 资源」的组合分别配置。例如同一个用户在订单资源上是「本部门」,在报表资源上是「自定义范围」。

3.2 行级与列级控制

数据权限有两个维度:

  • 行级控制:控制能看到哪些记录。实现上通常是在查询条件里附加一段由权限规则生成的过滤条件。
  • 列级控制:控制能看到记录里的哪些字段。例如敏感的手机号、身份证号、成本价,对不同角色展示或脱敏。

列级控制容易被遗漏。一个系统如果在行级做了严格隔离,但把所有字段都返回,那么获得任意一条记录的人就能看到全部敏感字段。列级控制应当与脱敏策略一起设计,而不是在前后端各自判断。

3.3 数据权限的求值时机

数据权限的求值位置决定了它的可靠性。如果只在应用层拼装查询条件,那么任何绕过应用层直接查库的入口(导出任务、定时报表、内部工具)都可能绕过数据权限。稳妥的做法是把数据权限作为数据访问层的一部分统一注入,让所有查询——无论是页面查询、导出还是异步任务——都经过同一套过滤逻辑。

四、多组织层级与作用域

集团或连锁类企业后台最大的特点是组织是有层级的:集团、区域、子公司、门店,层层向下。权限模型必须能表达这种层级,否则就只能用「每个人配一遍」的笨办法。

4.1 组织树与数据归属

基础工作是给每条业务数据标注它归属的组织节点。这个归属应当在数据产生时就确定下来,而不是事后靠部门字段去猜。归属字段一旦缺失或不一致,上层的「本部门及下级」过滤就无法正确计算。

组织树还需要考虑组织调整的历史。一个部门被拆分或合并后,历史数据仍归原组织,还是随调整一起迁移?这需要业务上给出一致规则,并在实现上保留组织树的变更历史,避免出现「数据归属指向一个已经不存在的节点」。

4.2 授权的作用域

授权本身也有作用域。同一条权限规则,在集团层配置表示「适用于全部下级」,在某个子公司配置表示「仅适用于该子公司」。如果不区分作用域,就会出现两种错误:子公司管理员改动了集团级的通用配置,或者集团统一配置无法被下级覆盖。

常见做法是把授权规则分为继承与覆盖两类:下级默认继承上级规则,需要时可以在本层增加更严格或更宽松的规则,并明确指出哪些层的配置可以覆盖上级。

五、越权防护

越权是权限系统最典型的失效形式,通常分为两类:

  • 水平越权:用户 A 通过修改请求参数,访问到了用户 B 的数据。例如把订单 ID 换成别人的,就能查到别人的订单。
  • 垂直越权:低权限用户通过直接访问高权限接口,执行了本不该执行的操作。例如普通用户直接调用管理员接口。

防护的核心原则是服务端不信任客户端传来的任何身份与范围信息。所有「我是谁」「我能看谁」的判断都必须在服务端从登录态推导,而不是从请求参数里读取。对于按 ID 访问的资源,需要在返回前校验该资源是否落在当前用户的数据权限范围内。

另一个常见疏漏是接口与页面权限不一致:页面隐藏了按钮,但接口没有校验,导致越权可以通过直接调接口完成。功能权限的校验必须放在接口层,页面隐藏只是体验优化,不是安全措施。

六、权限变更与审计

权限系统不只是「配置」,还需要「留痕」。审计要能回答三个问题:谁在什么时候获得了什么权限、谁在什么时候使用了什么权限、权限的变更由谁发起、依据是什么。

实现上建议至少保留两张日志:

  • 权限变更日志:记录角色与授权规则的增删改,包含操作人、时间、变更前后的内容。
  • 敏感操作日志:记录关键数据的访问与导出行为,尤其是批量导出。

审计日志本身也要受保护:不能被普通管理员删除或修改,且保留期限要符合行业要求。对于监管、医疗这类场景,留痕往往不是「可选项」而是硬性要求,具体可以参见 行业解决方案 中对应场景的说明。

七、落地建议

如果要把上面的内容收敛成可执行的建议,可以按下面的顺序推进。

第一步,先把权限定义成数据。 权限点、角色、数据权限规则都应当入库、可配置、可导出,而不是散落在代码里。这一步是所有后续工作的前提。

第二步,区分功能权限与数据权限。 功能权限描述「能做什么」,数据权限描述「能对谁做」,二者分开配置、分开演进。

第三步,把鉴权收敛到统一入口。 所有接口经过同一个鉴权层,数据权限作为数据访问层的一部分统一注入,避免出现绕过路径。

第四步,设计好组织层级与作用域。 明确授权规则的继承与覆盖关系,让集团与下级都能配置,同时不互相干扰。

第五步,把审计做进第一版。 权限变更日志与敏感操作日志不要留到二期,否则会失去大量历史痕迹。

完整的项目推进方式与各阶段产出物,可以参考 交付流程;如果你对权限模型中的具体取舍还有疑问,也可以先看看 常见问题 里的相关条目。

八、小结

权限模型的难点,不在于技术上的复杂度,而在于它是否可以配置、是否可以随组织变化而调整、是否可审计。一个设计得好的权限系统,在业务变化时表现为「改配置」,在设计得不好的系统里则表现为「改代码加发版」,甚至表现为一次数据泄露。

回到最初的问题:权限不该是项目末尾补上的一块逻辑,而应当是贯穿数据模型、接口设计、组织关系的一条主线。把它当成主线来设计,后期的维护成本会明显低于把它当成补丁。

广州科芃科技有限公司技术团队在企业后台与行业系统的开发中,会把权限模型作为方案评估的固定环节,先确认组织层级、数据归属与审计要求,再决定功能与数据权限的配置方式。相关能力说明见 软件研发服务。

关于本文:本文由广州科芃科技有限公司技术团队撰写,基于公开行业信息与我们在软件、人工智能应用开发中的工程实践整理,用于说明该主题下的问题结构与应对方法;文中不包含客户名称与未公开的项目细节。
FAQ

常见问题

RBAC 和企业后台常见的数据权限有什么区别?

RBAC 解决的是功能权限,即用户能不能进入某个菜单或调用某个接口;数据权限解决的是可见范围,即进入之后能看到哪些行、哪些列。很多系统第一版只做了功能权限,等业务方提出「不同区域的运营只能看自己区域的数据」时,才发现数据权限没有设计位置。二者应分开配置、分开演进,角色描述「能做什么」,数据权限描述「能对谁做」。

为什么权限角色会越来越多,怎么避免?

角色膨胀通常是因为把例外情况长期沉淀成了新角色。缓解办法是把角色分成两类:一类是职责角色,按岗位职责划分,数量有限且相对稳定;另一类是临时授权,用于短期、例外情况,有明确的生效期与到期回收机制。同时把「能做什么」与「能对谁做」拆开,组织调整时只改数据归属,不动角色定义。

水平越权和垂直越权分别指什么,怎么防?

水平越权是用户通过修改请求参数访问到他人的数据,例如把订单 ID 换成别人的;垂直越权是低权限用户直接访问高权限接口。防护的核心原则是服务端不信任客户端传来的任何身份与范围信息,所有判断都从登录态推导;对按 ID 访问的资源,返回前要校验是否落在当前用户的数据权限范围内。功能权限的校验必须放在接口层,页面隐藏按钮只是体验优化。

数据权限应该在哪里求值,为什么?

如果只在应用层拼装查询条件,任何绕过应用层直接查库的入口,例如导出任务、定时报表、内部工具,都可能绕过数据权限。稳妥做法是把数据权限作为数据访问层的一部分统一注入,让页面查询、导出与异步任务都经过同一套过滤逻辑,避免出现绕过路径。

集团企业的多组织层级权限该怎么设计?

基础工作是给每条业务数据标注它归属的组织节点,归属在数据产生时就确定,而不是事后靠部门字段去猜。授权本身也要区分作用域:把规则分为继承与覆盖两类,下级默认继承上级规则,需要时可在本层增加更严格或更宽松的规则。同时保留组织树的变更历史,避免数据归属指向一个已经不存在的节点。

权限审计至少要记录哪些内容?

至少保留两张日志:权限变更日志,记录角色与授权规则的增删改,含操作人、时间与变更前后内容;敏感操作日志,记录关键数据的访问与导出行为,尤其是批量导出。审计日志本身也要受保护,不能被普通管理员删除或修改,保留期限应符合行业要求。监管、医疗等场景中留痕往往是硬性要求。

聊聊你的行业场景

把你的业务场景和期望讲清楚,我们先判断技术上怎么实现最稳,再谈报价与周期。