数据隔离实现说明.md 2.9 KB

数据隔离实现说明

实现方案

本系统实现了基于 create_by 字段的数据隔离机制:

1. 核心组件

CreateByDataInterceptor (数据隔离拦截器)

  • 位置: com.payroll.filter.CreateByDataInterceptor
  • 功能: 拦截所有数据库查询,在SQL中自动添加 create_by = 当前用户ID 的过滤条件
  • 超级管理员例外: 超级管理员可以看到所有数据

SecurityUtils (安全工具类)

  • 位置: com.payroll.utils.SecurityUtils
  • 功能: 提供当前用户信息获取和权限判断
  • 关键方法:
    • getCurrentUserId(): 获取当前登录用户ID
    • isSuperAdmin(): 判断是否为超级管理员

MyMetaObjectHandler (自动填充处理器)

  • 位置: com.payroll.config.MyMetaObjectHandler
  • 功能: 在数据插入时自动填充 create_byupdate_by 字段

2. 工作原理

数据写入时

  1. 用户创建数据时,MyMetaObjectHandler 自动将当前用户ID填入 create_by 字段
  2. 同时也会填入 update_by 字段

数据读取时

  1. CreateByDataInterceptor 拦截所有查询SQL
  2. 如果是超级管理员,不添加任何过滤条件
  3. 如果是普通用户,在WHERE条件中添加 AND create_by = 当前用户ID
  4. 确保用户只能看到自己创建的数据

3. 超级管理员识别

超级管理员的判断依据(满足任一条件即可):

  • 角色名称为 "超级管理员"
  • 角色编码为 "ROLE_ADMIN"
  • 角色ID为 1

4. 配置说明

MybatisPlusConfig 配置

@Configuration
public class MybatisPlusConfig {
    
    @Autowired
    private CreateByDataInterceptor createByDataInterceptor;

    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        // 添加基于create_by的数据权限拦截器
        interceptor.addInnerInterceptor(new DataPermissionInterceptor(createByDataInterceptor));
        return interceptor;
    }
}

5. 使用示例

假设有一个员工表查询:

-- 原始SQL
SELECT * FROM sys_employee WHERE status = 1

-- 普通用户看到的实际SQL
SELECT * FROM sys_employee WHERE status = 1 AND create_by = 123

-- 超级管理员看到的实际SQL  
SELECT * FROM sys_employee WHERE status = 1

6. 注意事项

  1. 所有需要数据隔离的表都必须包含 create_by 字段
  2. 数据创建时必须确保能正确获取到当前用户信息
  3. 超级管理员账号需要正确配置角色信息
  4. 系统会自动处理各种查询场景(SELECT、UPDATE、DELETE等)

7. 测试验证

可以通过以下方式验证数据隔离是否生效:

  1. 用不同用户账号登录系统
  2. 查看数据列表,确认只能看到自己创建的数据
  3. 用超级管理员账号登录,确认能看到所有数据