You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot集成Spring Security与MongoDB时用户角色获取异常

解决方案

1. 修复MongoDB角色关联加载问题

@DocumentReference默认是延迟加载,导致appUser.getRoles()无法获取到数据。修改AppUser的roles字段:

@DocumentReference(lazy = false)
private Collection<UserRole> roles = new ArrayList<>();

或者在UserRepository的查询方法上添加@Fetch注解强制加载关联数据。

2. 确保JWT生成时写入角色信息

空指针异常的核心原因是JWT中没有rolesClaim。检查登录用的CustomAuthenticationFilter,在生成JWT时添加角色:

// 认证成功后生成JWT的逻辑示例
UserDetails userDetails = (UserDetails) authentication.getPrincipal();
String[] roles = userDetails.getAuthorities().stream()
    .map(GrantedAuthority::getAuthority)
    .toArray(String[]::new);

Algorithm algorithm = Algorithm.HMAC256(System.getenv("MY_APP_SECRET_KEY").getBytes());
String accessToken = JWT.create()
    .withSubject(userDetails.getUsername())
    .withExpiresAt(new Date(System.currentTimeMillis() + 10 * 60 * 1000))
    .withIssuer(request.getRequestURL().toString())
    .withClaim("roles", roles) // 必须写入角色
    .sign(algorithm);

// 将token返回给客户端
Map<String, String> tokens = new HashMap<>();
tokens.put("access_token", accessToken);
response.setContentType(APPLICATION_JSON_VALUE);
new ObjectMapper().writeValue(response.getOutputStream(), tokens);

3. 修复实体类toString的空指针风险

修改AppUser的toString方法,添加roles非空判断:

@Override
public String toString() {
    StringBuilder sb = new StringBuilder();
    sb.append("AppUser{")
            .append("id=").append(id)
            .append(", userName='").append(userName).append("'")
            .append(", email='").append(email).append("'")
            .append(", password='[PROTECTED]'") // 密码不要明文输出
            .append(", roles=[");
    if (roles != null) {
        for (UserRole role : roles) {
            sb.append(role.getName()).append(", ");
        }
        if (!roles.isEmpty()) {
            sb.setLength(sb.length() - 2);
        }
    }
    sb.append("]}");
    return sb.toString();
}

4. 统一Security配置中的路径匹配

修正权限配置和过滤器中的路径不一致问题:

// SecurityConfig中修改为统一路径
http.authorizeHttpRequests().requestMatchers("/api/v1/login/**","/api/v1/token/refresh/**").permitAll();

内容的提问来源于stack exchange,提问作者ABAB

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 04:57:07