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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 08:29:56