Spring Boot部门数据权限

在企业级应用开发中,数据权限是一项非常重要的功能。它可以用来限制用户只能访问属于自己部门的数据,从而保护敏感信息并提升系统的安全性。本文将介绍如何使用Spring Boot实现部门数据权限功能。

数据准备

首先,我们需要准备一个部门表和一个用户表。部门表包含部门ID和部门名称字段,用户表包含用户ID、用户名、所属部门ID等字段。这里使用MySQL数据库作为示例,可以执行以下SQL语句创建相关表:

CREATE TABLE department (
    id INT PRIMARY KEY,
    name VARCHAR(100)
);

CREATE TABLE user (
    id INT PRIMARY KEY,
    username VARCHAR(100),
    department_id INT,
    FOREIGN KEY (department_id) REFERENCES department(id)
);

配置数据源和JPA

在Spring Boot项目的application.properties文件中,配置数据库连接和JPA相关信息:

spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.username=root
spring.datasource.password=root
spring.jpa.database-platform=org.hibernate.dialect.MySQLDialect
spring.jpa.show-sql=true

定义实体类和数据访问层

创建部门实体类Department和用户实体类User,并使用JPA注解进行映射。同时,创建DepartmentRepositoryUserRepository接口,继承自JpaRepository

@Entity
@Table(name = "department")
public class Department {
    @Id
    private Long id;
    private String name;
    // getter and setter
}

@Entity
@Table(name = "user")
public class User {
    @Id
    private Long id;
    private String username;
    @ManyToOne
    @JoinColumn(name = "department_id")
    private Department department;
    // getter and setter
}

public interface DepartmentRepository extends JpaRepository<Department, Long> {
}

public interface UserRepository extends JpaRepository<User, Long> {
}

实现数据权限过滤

在Spring Boot中,可以使用自定义注解和AOP实现数据权限过滤。首先,创建一个@DataPermission注解,用于标记需要进行数据权限过滤的方法:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface DataPermission {
}

接下来,创建一个切面类DataPermissionAspect,其中的@Before注解用于在目标方法执行前进行数据权限过滤:

@Aspect
@Component
public class DataPermissionAspect {
    @Autowired
    private UserRepository userRepository;

    @Before("@annotation(DataPermission)")
    public void before(JoinPoint joinPoint) {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication != null && authentication.getPrincipal() instanceof UserDetails) {
            UserDetails userDetails = (UserDetails) authentication.getPrincipal();
            Long departmentId = userRepository.findByUsername(userDetails.getUsername()).getDepartment().getId();
            // 根据部门ID设置数据过滤条件
            // ...
        }
    }
}

在上述代码中,通过SecurityContextHolder.getContext().getAuthentication()获取当前登录用户信息,然后根据用户名查询用户所属部门的ID。接下来,可以根据部门ID设置数据过滤条件进行数据查询。

使用数据权限

在需要进行数据权限过滤的方法上,添加@DataPermission注解即可启用数据权限过滤:

@DataPermission
public List<User> getAllUsers() {
    return userRepository.findAll();
}

当用户调用getAllUsers方法时,会自动进行数据权限过滤,只返回属于用户所属部门的用户数据。

测试数据权限功能

为了测试数据权限功能,可以添加一些测试数据到数据库中:

@Autowired
private DepartmentRepository departmentRepository;
@Autowired
private UserRepository userRepository;

@PostConstruct
public void init() {
    Department department1 = new Department();
    department1.setId(1L);
    department1.setName("部门A");
    departmentRepository.save(department1);

    Department department2 = new Department();
    department2.setId(2L);
    department2.setName("部门B");
    departmentRepository.save(department2);

    User user1 = new User();
    user1.setId(1L);
    user1.setUsername("user1");
    user1.setDepartment(department1);
    userRepository.save(user1);

    User user2 = new User();
    user2.setId(2L);
    user2.setUsername("user2");
    user2.setDepartment(department2);
    userRepository.save(user2);
}

然后,在控制器中调用getAllUsers方法进行测试: