从原理到源码解析数据权限控制

📅 2026/7/23 3:50:45 👁️ 阅读次数 📝 编程学习
从原理到源码解析数据权限控制

在常规开发中,权限控制通常聚焦于两点:

  • 前端组件显示:控制菜单、按钮的可见性;
  • 后端接口访问:控制用户能否调用指定 URL。

但这两种权限控制的核心局限在于:它们管控的是不同的对象(如组件 A 与组件 B、接口 A 与接口 B),无法解决同一对象内的数据隔离问题。

实际业务中存在这类痛点:所有用户数据存储在同一张表中,要求不同部门的用户只能查看本部门数据。此时,同一查询接口、同一条 SQL,需要根据用户身份返回不同结果,而菜单权限无法实现这一需求,因此数据权限的引入成为必然。

一、问题引入:为什么需要数据权限?
在常规开发中,我们对权限的控制通常体现在两个方面 :

前端组件显示:控制菜单或按钮的显隐 。

后端接口访问:控制用户是否有权请求某个 URL 。

但这两种方式有一个共同特点:它们针对的往往不是同一个对象(比如组件 A 和组件 B,接口 A 和接口 B)。

现在的痛点是: 我们要针对同一个对象(例如“用户表”里的数据)进行控制 。假设所有用户数据都存在同一张表中,需求是:不同部门的用户只能看到自己部门的数据 。

如果仅仅使用菜单权限,无法解决“同一个接口(list)、同一个 SQL,却要返回不同结果”的问题。这就需要引入数据权限。

二、 解决方案与现象展示

RuoYi 框架通过在“角色管理”中配置“数据范围”来解决这个问题。

1.配置数据权限

管理员进入【系统管理 -> 角色管理】,可以为角色分配不同的数据权限范围 :

2. 实际效果


假设我们有两个用户:

admin(超级管理员):拥有全部数据权限 。

ry(普通角色):隶属于测试部门,仅拥有本部门数据权限 。

当他们分别访问同一个【用户管理】页面时:

admin 能看到研发部门、测试部门等所有公司的用户数据 。

ry 只能看到测试部门的 1 条数据,其他数据被自动过滤 。

数据权限的本质,其实就是修改 SQL 语句 。RuoYi 利用 AOP(面向切面编程)和 MyBatis 的动态 SQL 能力,实现了这一过程的自动化。

3.后端源码分析


第1步:Controller 发起请求

第2步:进入 Service 实现类

第3步:AOP 切面拦截(核心!)

当调用带有 @DataScope 注解的方法时,DataScopeAspect.java 会拦截:

第4步:handleDataScope 方法处理

第5步:dataScopeFilter 生成SQL条件

第6步:进入 Mapper 执行SQL

第7步:XML 中的 SQL 拼接

总结流程图

总结


RuoYi 的数据权限实现是 AOP + 动态 SQL 的经典应用。

作用:限制同一类型数据的不同行 。

操作:给角色配置数据权限,给用户分配角色 。

原理:

Service 层使用 @DataScope 定义别名 。

Aspect 层根据注解和用户信息,动态生成 SQL 过滤片段 。

Mapper 层通过 ${params.dataScope} 将过滤条件注入 SQL 。

通过这种方式,我们不仅实现了灵活的权限控制,还将权限逻辑与业务逻辑彻底解耦,极大地提高了代码的可维护性。

车间的设备数据设计数据权限

(1).创建设备实体类 Equipment.java

(2).创建设备Mapper接口 IEquipmentMapper.java

(3).创建设备Mapper XML配置文件

(4).创建设备Service接口 IEquipmentService.java

(5).创建设备Service实现类 EquipmentServiceImpl.java

(6).创建设备Controller控制器

(7).创建数据库建表SQL脚本

演示

  1. 分配菜单权限和数据权限给普通角色

超级用户赋予普通用户一定的权限,安装位置数据没给授权,那么ry用户哪里就不会显示

如果超级用户没给予车间权限,ry用户不会显示