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
相关产品推荐
相关产品推荐

