UserDetails 及角色权限管理

本项目采用了 Spring Security 进行安全管理,主要包括用户认证和授权。以下是一些关键点的说明:

用户角色

在本项目中,用户角色主要分为两类:

  • ROLE_USER:普通用户,拥有基本的访问权限。
  • ROLE_ADMIN:管理员用户,拥有更高的权限,可以进行管理操作。

主要在 CustomUserDetailsService 类中为用户分配角色:

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
55
56
package com.test.security.service;

import com.test.entity.Teacher;
import com.test.mapper.TeacherMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Service
public class CustomUserDetailsService implements UserDetailsService {

@Autowired
private TeacherMapper teacherMapper;

@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
// 从数据库加载教师信息
Teacher teacher = teacherMapper.getByUsername(username);

if (teacher == null) {
throw new UsernameNotFoundException("User not found: " + username);
}

// 获取数据库中的加密密码
String encodedPassword = teacher.getPassword();

// 创建权限/角色列表
List<GrantedAuthority> authorities = new ArrayList<>();

// 根据教师角色添加相应的权限
// 注意:这里假设 teacher.getRole() 返回的是 "USER" 或类似字符串
// 使用 Spring Security 的角色前缀 "ROLE_"
if ("USER".equals(teacher.getRole())) {
authorities.add(new SimpleGrantedAuthority("ROLE_USER"));
} else if ("ADMIN".equals(teacher.getRole())) {
authorities.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
authorities.add(new SimpleGrantedAuthority("ROLE_USER")); // 管理员通常也有用户权限
}

// 创建并返回 UserDetails 对象
// 注意:这里返回的是 Spring Security 的 User 对象,不是 Teacher 实体
return org.springframework.security.core.userdetails.User
.withUsername(teacher.getUsername())
.password(encodedPassword) // 这里直接使用数据库中已加密的密码
.authorities(authorities)
.build();
}
}

这里的角色判断主要用于Spring Security的权限控制。可以在以下几个地方使用这些角色:

  • 方法级别的权限控制

    在Controller或Service方法上使用@PreAuthorize、@Secured等注解。例如:

    1
    2
    3
    4
    @PreAuthorize("hasRole('ADMIN')")
    public void adminOnlyMethod() {
    // 只有ADMIN角色可以访问
    }
  • URL 级别的权限控制

    在Spring Security的配置类(如WebSecurityConfigurerAdapter的实现类)中配置不同URL的访问权限。例如:

    1
    2
    3
    4
    http.authorizeRequests()
    .antMatchers("/admin/**").hasRole("ADMIN")
    .antMatchers("/user/**").hasRole("USER")
    .anyRequest().authenticated();

    前端页面显示控制
    前端可以根据当前用户的角色显示或隐藏某些页面元素(如按钮、菜单等)。
    这些角色判断的本质是为Spring Security提供用户的权限信息,后续Spring Security会根据这些角色自动进行访问控制。

我们选择使用 URL 级别的权限控制,结合 JWT 进行认证和授权,确保系统的安全性和灵活性。