程序员scholar 程序员scholar
首页
  • Java 基础

    • JavaSE
    • JavaIO
    • JavaAPI速查
  • Java 高级

    • JUC
    • JVM
    • Java新特性
    • 设计模式
  • Web 开发

    • Servlet
    • Java网络编程
  • Web 标准

    • HTML
    • CSS
    • JavaScript
  • 前端框架

    • Vue2
    • Vue3
    • 微信小程序
    • uni-app
  • 工具与库

    • jQuery
    • Ajax
    • Axios
    • Webpack
    • Vuex
    • WebSocket
    • 第三方登录
  • 后端与语言扩展

    • ES6
    • Typescript
    • node.js
  • Element-UI
  • Apache ECharts
  • 数据结构
  • HTTP协议
  • HTTPS协议
  • 计算机网络
  • Linux常用命令
  • Windows常用命令
  • SQL数据库

    • MySQL
    • MySQL速查
  • NoSQL数据库

    • Redis
    • ElasticSearch
  • 数据库

    • MyBatis
    • MyBatis-Plus
  • 消息中间件

    • RabbitMQ
  • 服务器

    • Nginx
  • Spring框架

    • Spring6
    • SpringMVC
    • SpringBoot
    • SpringSecurity
  • SpringCould微服务

    • SpringCloud基础
    • 微服务之DDD架构思想
  • 日常必备

    • 开发常用工具包
    • Hutoll工具包
    • IDEA常用配置
    • 开发笔记
    • 若依框架
    • 日常记录
    • 项目部署
    • 网站导航
    • 产品学习
    • 英语学习
  • 代码管理

    • Maven
    • Git教程
    • Git小乌龟教程
  • 运维工具

    • Docker
    • Jenkins
    • Kubernetes
  • 算法笔记

    • 算法思想
    • 刷题笔记
  • 面试问题常见

    • 十大经典排序算法
    • 面试常见问题集锦
关于
GitHub (opens new window)
首页
  • Java 基础

    • JavaSE
    • JavaIO
    • JavaAPI速查
  • Java 高级

    • JUC
    • JVM
    • Java新特性
    • 设计模式
  • Web 开发

    • Servlet
    • Java网络编程
  • Web 标准

    • HTML
    • CSS
    • JavaScript
  • 前端框架

    • Vue2
    • Vue3
    • 微信小程序
    • uni-app
  • 工具与库

    • jQuery
    • Ajax
    • Axios
    • Webpack
    • Vuex
    • WebSocket
    • 第三方登录
  • 后端与语言扩展

    • ES6
    • Typescript
    • node.js
  • Element-UI
  • Apache ECharts
  • 数据结构
  • HTTP协议
  • HTTPS协议
  • 计算机网络
  • Linux常用命令
  • Windows常用命令
  • SQL数据库

    • MySQL
    • MySQL速查
  • NoSQL数据库

    • Redis
    • ElasticSearch
  • 数据库

    • MyBatis
    • MyBatis-Plus
  • 消息中间件

    • RabbitMQ
  • 服务器

    • Nginx
  • Spring框架

    • Spring6
    • SpringMVC
    • SpringBoot
    • SpringSecurity
  • SpringCould微服务

    • SpringCloud基础
    • 微服务之DDD架构思想
  • 日常必备

    • 开发常用工具包
    • Hutoll工具包
    • IDEA常用配置
    • 开发笔记
    • 若依框架
    • 日常记录
    • 项目部署
    • 网站导航
    • 产品学习
    • 英语学习
  • 代码管理

    • Maven
    • Git教程
    • Git小乌龟教程
  • 运维工具

    • Docker
    • Jenkins
    • Kubernetes
  • 算法笔记

    • 算法思想
    • 刷题笔记
  • 面试问题常见

    • 十大经典排序算法
    • 面试常见问题集锦
关于
GitHub (opens new window)
npm

(进入注册为作者充电)

  • 快速入门

  • 后端手册

    • 分页实现
    • 导入导出功能
    • 文件上传与下载
    • 权限注解实现
    • 事务管理详解
    • 全局异常处理
    • 参数验证详解
    • 数据脱敏详解
    • 系统日志功能实现
    • 数据权限控制
      • 一、数据权限注解 @DataScope 参数说明
        • 1. deptAlias 参数
        • 2. userAlias 参数
      • 二、数据权限的配置和使用
        • 1. 配置数据权限
        • 2. 数据权限控制的使用
      • 三、SQL 查询中的数据权限过滤
        • 1. 未过滤数据权限的 SQL 查询示例
        • 2. 已过滤数据权限的 SQL 查询示例
        • 3. 在 MyBatis 查询中添加数据范围过滤
      • 四、数据权限的逻辑实现
        • 1. DataScopeAspect 切面类
        • 2. 通过 BaseEntity 实现数据权限控制
      • 五、总结
    • 多数据源实现
    • 代码生成功能
    • 定时任务实现
    • 系统接口文档生成
    • 防重复提交实现
    • 国际化支持
    • 新建子模块
  • 前端手册

  • 组件文档

  • 数据库分析

  • 若依框架
  • 后端手册
scholar
2024-08-31
目录

数据权限控制

# 数据权限控制

在企业级应用中,数据权限控制是一项重要的功能,用于确保用户只能访问与其角色和部门权限相符的数据。若依框架提供了一套完整的数据权限控制机制,通过注解和拦截器结合 MyBatis 实现了灵活的权限管理。本文将详细介绍若依框架中数据权限的实现方法,包括注解的使用、数据权限的配置和 SQL 查询的过滤逻辑。

# 一、数据权限注解 @DataScope 参数说明

若依框架提供的 @DataScope 注解用于标注需要进行数据权限控制的业务方法。通过配置注解参数,可以指定部门表和用户表的别名,从而实现基于部门和用户的数据权限过滤。

参数 类型 默认值 描述
deptAlias String 空 部门表的别名,用于SQL查询过滤
userAlias String 空 用户表的别名,用于SQL查询过滤

# 1. deptAlias 参数

deptAlias 参数用于指定部门表的别名。当业务 SQL 查询中涉及部门数据权限过滤时,需要为部门表设置别名,并在 @DataScope 注解中使用该别名。

@DataScope(deptAlias = "d")
public List<User> selectUserList(User user)
{
    return userMapper.selectUserList(user);
}
1
2
3
4
5

# 2. userAlias 参数

userAlias 参数用于指定用户表的别名。当业务 SQL 查询中需要同时过滤用户和部门数据权限时,使用 userAlias 参数设置用户表的别名。

@DataScope(deptAlias = "d", userAlias = "u")
public List<User> selectUserList(User user)
{
    return userMapper.selectUserList(user);
}
1
2
3
4
5

# 二、数据权限的配置和使用

在若依框架中,数据权限主要通过角色配置来实现。管理员可以在角色管理中为角色配置数据权限范围,并通过 @DataScope 注解结合 MyBatis SQL 查询,实现对数据的权限控制。

# 1. 配置数据权限

在“系统管理 - 角色管理”中,可以为角色配置数据权限。若依框架支持以下几种数据权限配置:

  • 全部数据权限:角色可以访问系统中的所有数据。
  • 自定义数据权限:角色可以访问管理员指定的数据范围。
  • 部门数据权限:角色只能访问自己所在部门的数据。
  • 部门及以下数据权限:角色可以访问自己所在部门及其下属部门的数据。
  • 仅本人数据权限:角色只能访问自己创建的数据。

# 2. 数据权限控制的使用

在业务方法上使用 @DataScope 注解,通过设置 deptAlias 和 userAlias 参数来实现数据权限的控制。

  • 部门数据权限注解:
@DataScope(deptAlias = "d")
public List<User> selectUserList(User user)
{
    return userMapper.selectUserList(user);
}
1
2
3
4
5
  • 部门及用户数据权限注解:
@DataScope(deptAlias = "d", userAlias = "u")
public List<User> selectUserList(User user)
{
    return userMapper.selectUserList(user);
}
1
2
3
4
5

# 三、SQL 查询中的数据权限过滤

在使用 @DataScope 注解的方法中,MyBatis 会自动在 SQL 查询中添加数据权限的过滤条件。开发者只需在 MyBatis 的 XML 配置中使用 ${params.dataScope} 即可实现自动的权限过滤。

# 1. 未过滤数据权限的 SQL 查询示例

以下是用户管理中,未进行数据权限过滤的 SQL 查询示例:

select u.user_id, u.dept_id, u.login_name, u.user_name, u.email,
       u.phonenumber, u.password, u.sex, u.avatar, u.salt,
       u.status, u.del_flag, u.login_ip, u.login_date, u.create_by,
       u.create_time, u.remark, d.dept_name
from sys_user u
left join sys_dept d on u.dept_id = d.dept_id
where u.del_flag = '0'
1
2
3
4
5
6
7

# 2. 已过滤数据权限的 SQL 查询示例

在进行数据权限过滤后,SQL 查询会自动添加相应的条件:

select u.user_id, u.dept_id, u.login_name, u.user_name, u.email,
       u.phonenumber, u.password, u.sex, u.avatar, u.salt,
       u.status, u.del_flag, u.login_ip, u.login_date, u.create_by,
       u.create_time, u.remark, d.dept_name
from sys_user u
left join sys_dept d on u.dept_id = d.dept_id
where u.del_flag = '0'
  and u.dept_id in (
    select dept_id
    from sys_role_dept
    where role_id = #{roleId}
  )
1
2
3
4
5
6
7
8
9
10
11
12

通过角色部门表(sys_role_dept)完成数据权限过滤。

# 3. 在 MyBatis 查询中添加数据范围过滤

在 MyBatis 的 XML 配置文件中,使用 ${params.dataScope} 来插入数据权限过滤条件。

<select id="selectUserList" parameterType="com.ruoyi.system.domain.User" resultMap="BaseResultMap">
    select u.user_id, u.dept_id, u.login_name, u.user_name, u.email,
           u.phonenumber, u.password, u.sex, u.avatar, u.salt,
           u.status, u.del_flag, u.login_ip, u.login_date, u.create_by,
           u.create_time, u.remark, d.dept_name
    from sys_user u
    left join sys_dept d on u.dept_id = d.dept_id
    where u.del_flag = '0'
      ${params.dataScope}
</select>
1
2
3
4
5
6
7
8
9
10

# 四、数据权限的逻辑实现

数据权限的核心逻辑是通过 AOP 切面和 MyBatis 拦截器来实现的。在若依框架中,DataScopeAspect 切面类负责拦截标记了 @DataScope 注解的方法,并动态生成数据权限的 SQL 片段,注入到查询中。

# 1. DataScopeAspect 切面类

DataScopeAspect 切面类通过拦截标注了 @DataScope 注解的方法,解析注解参数,并将生成的数据权限 SQL 片段注入到 MyBatis 查询参数中。

package com.ruoyi.framework.aspectj;

import com.ruoyi.common.annotation.DataScope;
import com.ruoyi.common.core.domain.BaseEntity;
import com.ruoyi.common.utils.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

import java.util.Map;

@Aspect
@Component
public class DataScopeAspect
{
    @Before("@annotation(dataScope)")
    public void doBefore(JoinPoint point, DataScope dataScope)
    {
        // 获取方法参数
        Object params = point.getArgs()[0];
        if (params != null && params instanceof BaseEntity)
        {
            BaseEntity baseEntity = (BaseEntity) params;
            Map<String, Object> dataScopeMap = baseEntity.getParams();
            if (StringUtils.isNotEmpty(dataScope.deptAlias()))
            {
                dataScopeMap.put("dataScope", getDeptDataScope(dataScope.deptAlias()));
            }
            if (StringUtils.isNotEmpty(dataScope.userAlias()))
            {
                dataScopeMap.put("dataScope", getUserDataScope(dataScope.userAlias()));
            }
        }
    }

    // 部门数据权限过滤逻辑
    private String getDeptDataScope(String deptAlias)
    {
        // 根据角色获取部门数据权限
        // 示例:and d.dept_id in (select dept_id from sys_role_dept where role_id = ?)
        return StringUtils.format(
            "and {}.dept_id in (select dept_id from sys_role_dept where role_id = ?)", deptAlias);
    }

    // 用户数据权限过滤逻辑
    private String getUserDataScope(String userAlias)
    {
        // 根据用户获取数据权限
        // 示例:and u.user_id in (select user_id from sys_role_user where role_id = ?)
        return StringUtils.format(
            "and {}.user_id in (select user_id from sys_role_user where role_id = ?)", userAlias);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54

# 2. 通过 BaseEntity 实现数据权限控制

数据权限 SQL 片段会存储到 BaseEntity 对象中的 params 属性中,并通过 ${params.dataScope} 在 MyBatis XML 文件中进行动态拼接,实现数据权限控制。

public class BaseEntity
{
    private Map<String, Object> params;

    public Map<String, Object> getParams()
    {
        return params;
    }

    public void setParams(Map<String, Object> params)
    {
        this.params = params;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 五、总结

通过 @DataScope 注解结合 MyBatis 拦截器,若依框架实现了灵活且强大的数据权限控制机制,确保不同角色的用户只能访问符合其权限的数据。

  • 数据权限配置: 在角色管理中配置不同的数据权限范围,支持多种权限模式,如全部数据、自定义数据、部门数据、仅本人数据等。
  • 注解使用简便: 通过 @DataScope 注解,轻松实现数据权限控制,无需手动编写复杂的 SQL 查询。
  • SQL 查询过滤: 数据权限过滤条件会自动拼接到 SQL 查询中,确保查询结果符合数据权限的要求。
  • 灵活扩展: 可以根据实际业务需求,自定义数据权限的过滤逻辑和 SQL 拼接方式,满足不同场景的需求。
编辑此页 (opens new window)
上次更新: 2024/12/28, 18:32:08
系统日志功能实现
多数据源实现

← 系统日志功能实现 多数据源实现→

Theme by Vdoing | Copyright © 2019-2025 程序员scholar
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式