Spring Boot访问/manage/**端点提示未授权的问题排查
问题分析与解决
1. 注册用户未被分配ADMIN角色
在AuthController的register方法中,代码硬编码为用户分配了USER角色,而非期望的ADMIN角色:
Role roles = roleRepository.findByName("USER").orElse(null); user.setRoles(Collections.singletonList(roles));
修改方法:
如果要注册ADMIN用户,需要查询ADMIN角色并分配,同时确保MongoDB的roles集合中存在该角色文档:
Role adminRole = roleRepository.findByName("ADMIN") .orElseThrow(() -> new RuntimeException("ADMIN角色不存在,请先初始化")); user.setRoles(Collections.singletonList(adminRole));
2. JWT过滤器未从Cookie中读取Token
JWTAuthenticationFilter的getJWTFromRequest方法仅从Authorization请求头读取Bearer Token,但登录时AuthController是将Token存入了名为jwtToken的Cookie中,导致过滤器无法获取Token进行认证:
private String getJWTFromRequest(HttpServletRequest request) { String bearerToken = request.getHeader("Authorization"); if(StringUtils.hasText(bearerToken) && bearerToken.startsWith("Bearer ")) { return bearerToken.substring(7); } return null; }
修改方法:
修改方法优先从Cookie中获取Token:
private String getJWTFromRequest(HttpServletRequest request) { // 先从Cookie读取token Cookie[] cookies = request.getCookies(); if (cookies != null) { for (Cookie cookie : cookies) { if ("jwtToken".equals(cookie.getName())) { return cookie.getValue(); } } } // 兼容从Authorization头读取的情况 String bearerToken = request.getHeader("Authorization"); if(StringUtils.hasText(bearerToken) && bearerToken.startsWith("Bearer ")) { return bearerToken.substring(7); } return null; }
3. Spring Security角色前缀不匹配
SecurityConfig中使用hasRole("ADMIN")进行权限控制,Spring Security会自动为角色名添加ROLE_前缀(实际校验权限为ROLE_ADMIN),但CustomUserDetailsService中直接将角色名作为权限标识,导致权限匹配失败:
// SecurityConfig中的配置 .requestMatchers("/manage/**").hasRole("ADMIN") // CustomUserDetailsService中的代码 private Collection<GrantedAuthority> mapRolesToAuthorities(List<Role> roles) { return roles.stream().map(role -> new SimpleGrantedAuthority(role.getName())) .collect(Collectors.toList()); }
修改方法(二选一):
- 方法一:转换角色时添加
ROLE_前缀
private Collection<GrantedAuthority> mapRolesToAuthorities(List<Role> roles) { return roles.stream() .map(role -> new SimpleGrantedAuthority("ROLE_" + role.getName())) .collect(Collectors.toList()); }
- 方法二:使用
hasAuthority替代hasRole,直接匹配角色名
// 修改SecurityConfig中的权限配置 .requestMatchers("/manage/**").hasAuthority("ADMIN")
内容的提问来源于stack exchange,提问作者GPPiotr
相关产品推荐
相关产品推荐

