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

Spring Boot JWT角色认证加@PreAuthorize报Full authentication错误如何解决

问题排查及解决方案

你遇到的full authentication is required to access this resource报错,本质是方法级鉴权时,Spring Security上下文没有找到有效的已认证信息,可按以下顺序排查修复:

1. 修正Security配置冲突

你当前配置中.antMatchers("/**").permitAll()和.anyRequest().authenticated()逻辑完全冲突,/**会匹配所有路径,导致后面的anyRequest规则完全不生效。需要调整为仅放行无需认证的公开接口,示例如下:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.cors().and().csrf().disable().exceptionHandling().authenticationEntryPoint(unauthorizeHandler)
            .and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
            .and().authorizeRequests()
            // 仅放行登录、注册等公开接口,替换为你自己的公开路径
            .antMatchers("/api/auth/**", "/public/**").permitAll()
            .anyRequest().authenticated();

    http.addFilterBefore(authenticationJwtTokenFilter(), UsernamePasswordAuthenticationFilter.class);
}

2. 检查AuthTokenFilter的核心逻辑

90%以上的同类问题都是JWT解析完成后没有将认证信息写入Spring Security上下文,确保你的Filter包含以下逻辑:

// 1. 从请求头提取Bearer Token
String authHeader = request.getHeader("Authorization");
if (StringUtils.hasText(authHeader) && authHeader.startsWith("Bearer ")) {
    String jwt = authHeader.substring(7);
    // 2. 验证JWT有效性,解析用户名
    String username = jwtUtils.getUserNameFromJwtToken(jwt);
    if (StringUtils.hasText(username) && SecurityContextHolder.getContext().getAuthentication() == null) {
        // 3. 加载用户及对应的角色权限
        UserDetails userDetails = userDetailsServices.loadUserByUsername(username);
        if (jwtUtils.validateJwtToken(jwt, userDetails)) {
            // 4. 构造认证对象,必须传入用户权限列表
            UsernamePasswordAuthenticationToken authentication = 
                new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
            authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
            // 5. 写入Security上下文,这步是核心,缺失就会报认证不足的错误
            SecurityContextHolder.getContext().setAuthentication(authentication);
        }
    }
}
filterChain.doFilter(request, response);

3. 修正角色匹配逻辑

Spring Security的hasRole注解默认会自动拼接ROLE_前缀:

  • 如果你的数据库中角色存储格式为ROLE_USER,直接用@PreAuthorize("hasAuthority('ROLE_USER')")即可,hasAuthority不会自动加前缀,避免匹配错误
  • 如果你的数据库中角色存储格式为USER,用@PreAuthorize("hasRole('USER')")即可,框架会自动匹配ROLE_USER

4. 本地调试验证

在AuthEntryPointJwt的commence方法中加断点,查看AuthenticationException的具体类型:

  • 如果是BadCredentialsException:JWT无效、过期或解析失败
  • 如果是AccessDeniedException:用户角色和注解要求不匹配
  • 如果上下文无Authentication对象:说明Filter逻辑缺失,走第二步排查

内容的提问来源于stack exchange,提问作者Đoàn Đức Tín

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 04:36:05