企业级权限系统怎么设计三 —— 数据权限控制

企业级权限系统怎么设计三 ------ 数据权限控制

前两篇文章,我们主要梳理了权限系统中的功能权限的设计。功能权限解决了"用户能做什么操作"的问题,但企业应用中还有另外一种权限:用户能对哪些数据 进行这些操作?即数据权限

一个典型的场景是:销售部的张三和李四都能使用"查看订单"的功能,但张三可能只能看自己负责的订单,而李四作为经理,可以看到本部门所有销售的订单。这就是数据权限在起作用。

注:本文不仅总结了常见的数据权限设计方案,也整理了更复杂但尚未完全落地的模型,供未来扩展和复杂场景参考。

数据权限的构成:行级权限与列级权限

数据权限一般包含两大维度:行级权限和列级权限

  • 行级权限控制"哪些记录"可见,比如某用户只能查看自己的订单、本部门的订单或指定部门的数据等。
  • 列级权限控制"哪些字段"可见,比如一个用户只能看到客户表中的姓名和联系方式,其他敏感字段(如身份证号、收入)不可见,或需要脱敏处理。

可以理解为:行级权限决定数据的范围,列级权限决定访问的数据内容(字段)

实现方案的演进

下边我们逐步用更加灵活的模型来支持不同复杂度的业务,当然越灵活的模型带来运维成本,技术复杂度也在逐步提升,在实际场景中请合理选择。

方式一:硬编码 ------ 适用简单场景

最直接的做法是在 SQL 或代码中写死限制逻辑。

sql 复制代码
-- 仅查看本部门及下属部门数据的示例
-- 查询仅查看自己数据
SELECT * FROM orders WHERE user_id = #{currentUserId};

-- 查询本部门及下级部门数据,部门ID集合作为参数传入
SELECT * FROM orders WHERE dept_id IN (#{deptIdList});
  • 优点: 快速实现,适合固定规则。
  • 缺点: 灵活性差,无法动态配置,维护成本高。

方式二:RBAC + 数据范围 ------ 覆盖主流归属场景

在权限点绑定的基础上,加上数据范围的控制。

表结构示例:

role_id permission_code data_scope
1001 TRANSFER_QUERY DEPT_AND_BELOW
1002 LOAN_APPROVE SELF
1003 CUSTOMER_QUERY CUSTOM_DEPT(dept1, dept2)

data_scope 字段常见取值:

  • SELF:仅本人数据
  • DEPT:本部门数据
  • DEPT_AND_BELOW:本部门及下级部门
  • ALL:所有数据
  • CUSTOM_DEPT(dept1, dept2):指定多个部门

方式三:策略表达式模式 ------ 表达更复杂的数据规则

当范围控制不够用时,可以用策略表达式表述更灵活的条件,比如金额阈值、业务状态、地区等。

示例表结构

erDiagram DATA_POLICY { int id PK varchar policy_code "策略代码,便于配置和识别" varchar subject_type "主体类型 (role/user)" varchar subject_id "主体ID" int permission_point_id "权限点ID" } DATA_POLICY_GROUP { int id PK int policy_id FK "关联的策略ID" varchar group_code "条件组代码,便于内部识别" varchar name "条件组名称,便于后台维护" varchar logical_op "组内条件的逻辑操作 (AND/OR)" } DATA_POLICY_CONDITION { int id PK int group_id FK "关联的条件组ID" varchar field "条件字段" varchar operator "条件操作符" varchar value_type "值类型 (const/userAttr)" varchar value_expr "值表达式" } DATA_POLICY ||--|{ DATA_POLICY_GROUP : "包含条件组" DATA_POLICY_GROUP ||--|{ DATA_POLICY_CONDITION : "包含条件"

可表达:金额大于 50 万,且(状态为已审批 或 区域为华北)

方式四:ABAC 模型 ------ 适用于复杂/平台级系统

ABAC(Attribute-Based Access Control)模型,从"属性"出发控制访问,属性可来自用户、资源或环境,适用于复杂动态的权限决策(既能控制功能权限,也能控制数据权限)。

ABAC 模型强调策略与主体解耦,通常采用如下结构:

示例表结构
erDiagram ABAC_BINDING { varchar subject_type "主体类型 (user/role)" varchar subject_id "主体ID" int policy_id FK "关联的ABAC策略ID" } ABAC_POLICY { int policy_id PK varchar policy_code "策略代码,便于配置和识别" varchar policy_name "策略名称" varchar resource "资源标识" varchar action "操作标识" varchar pre_condition_expr "策略前置条件表达式" boolean enabled "策略是否启用" } ABAC_POLICY_GROUP { int id PK int policy_id FK "关联的ABAC策略ID" varchar group_code "条件组代码,便于内部识别" varchar name "条件组名称,便于后台维护" varchar logical_op "组内条件的逻辑操作 (AND/OR)" } ABAC_POLICY_CONDITION { int id PK int group_id FK varchar field "条件字段" varchar operator "条件操作符" varchar value_type "值类型 (const/userAttr)" varchar value_expr "值表达式" } ABAC_POLICY ||--|{ ABAC_BINDING : "被绑定到主体" ABAC_POLICY ||--|{ ABAC_POLICY_GROUP : "包含条件组" ABAC_POLICY_GROUP ||--|{ ABAC_POLICY_CONDITION : "包含条件"
为什么需要 resource 和 action 字段?
  • resource 标识策略适用的资源对象,比如 orderloancustomer 等;
  • action 标识操作行为,比如 view(查看)、edit(编辑)、approve(审批)等;

通过资源 + 动作 联合定位,可以让一条策略精准适配对应的操作上下文,避免因资源或动作不同导致误匹配。

同时也方便后续支持不同资源下的统一权限管理。

为什么需要 ABAC_BINDING 表?
  • 性能考虑:通过绑定用户或角色,快速缩小策略检索范围,避免海量策略全表扫描。
  • 灵活配置:既可以针对单个用户授权,也可以针对角色、组织授权,适配不同组织模型。
  • 管理方便:权限配置界面可以更清晰地展现策略与用户/角色的对应关系。

注:在高并发或超大规模系统中,绑定表也可以结合缓存、预编译策略等方式,进一步加速策略匹配。


以上就是企业级权限系统中数据权限控制的四种典型方案,从简单到复杂,从静态到动态,既可以按需选择,也可以组合使用。

下一篇我们将继续深入,探讨ABAC模型同时实现功能权限和数据权限以及字段脱敏、审计日志等延展问题

相关推荐
我的golang之路果然有问题26 分钟前
案例速成GO+redis 个人笔记
经验分享·redis·笔记·后端·学习·golang·go
嘻嘻嘻嘻嘻嘻ys37 分钟前
《Vue 3.3响应式革新与TypeScript高效开发实战指南》
前端·后端
暮乘白帝过重山1 小时前
路由逻辑由 Exchange 和 Binding(绑定) 决定” 的含义
开发语言·后端·中间件·路由流程
CHQIUU1 小时前
告别手动映射:在 Spring Boot 3 中优雅集成 MapStruct
spring boot·后端·状态模式
广西千灵通网络科技有限公司1 小时前
基于Django的个性化股票交易管理系统
后端·python·django
CodeFox1 小时前
动态线程池 v1.2.1 版本发布,告警规则重构,bytebuddy 替换 cglib,新增 jmh 基准测试等!
java·后端
tonydf1 小时前
0帧起手本地跑一下BitNet
后端·ai编程
zzmgc41 小时前
常用JVM配置参数
后端
金融数据出海1 小时前
使用PHP对接印度股票市场数据
后端
[email protected]1 小时前
ASP.NET Core自动事务ActionFilter
后端·asp.net·.netcore