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

Spring Boot3+Spring Security6认证成功后仍返回匿名用户问题

问题描述

使用Spring Boot 3.0.6 + Spring Security 6.x开发,JwtAuthenticationFilter中已通过UsernamePasswordAuthenticationToken将认证信息存入SecurityContextHolder,日志也验证了认证信息已成功设置,但用Postman访问/api/auth/r/testing接口时,返回结果为anonymousUser。

代码问题分析

核心问题在于没有将JWT过滤器纳入Spring Security的过滤器链管理,而是通过FilterRegistrationBean注册成了Servlet容器级别的过滤器,导致Spring Security无法正确识别并维护你设置的认证上下文:

  1. WebSecurityConfig中注入了JwtAuthenticationFilter实例,但未将其添加到SecurityFilterChain中,Spring Security的过滤器链无法感知到你设置的认证信息。
  2. 虽然用FilterRegistrationBean设置了最高优先级,但Spring Security的SecurityContextPersistenceFilter会在请求流程中管理上下文,Servlet级过滤器设置的上下文可能被后续Spring Security的过滤器操作覆盖或重置。
解决方案

步骤1:删除FilterConfig类

无需通过FilterRegistrationBean注册JWT过滤器,交由Spring Security的过滤器链管理即可。

步骤2:修改WebSecurityConfig,将JWT过滤器加入Spring Security过滤器链

在filterChain方法中,添加addFilterBefore将JWT过滤器放到UsernamePasswordAuthenticationFilter之前执行:

@Configuration
@EnableWebSecurity
public class WebSecurityConfig{
    @Resource
    private JwtAuthenticationFilter jwtAuthenticationFilter;

    @Resource(name = "jwtService")
    private UserDetailsService userDetailsService;

    @Bean
    public PasswordEncoder encoder(){
        return new BCryptPasswordEncoder();
    }

    @Bean
    public AuthenticationManager authenticationManager(AuthenticationConfiguration config) throws Exception {
        return config.getAuthenticationManager();
    }

    @Bean
    public AuthenticationProvider authenticationProvider(){
        DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
        authenticationProvider.setUserDetailsService(userDetailsService);
        authenticationProvider.setPasswordEncoder(encoder());
        return authenticationProvider;
    }
    
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception{
        http.cors().and()
                .csrf().disable()
                .authorizeHttpRequests()
                .requestMatchers("/api/auth/n/**").permitAll()
                .requestMatchers("/api/auth/r/**").permitAll()
                .anyRequest().authenticated() // 可根据实际需求调整其他请求的认证规则
                .and()
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .authenticationProvider(authenticationProvider())
                // 将JWT过滤器加入Spring Security过滤器链,放在用户名密码认证过滤器之前
                .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);

        return http.build();
    }
}

步骤3:确保JwtAuthenticationFilter是Spring管理的Bean

在JwtAuthenticationFilter类上添加@Component注解,让Spring自动管理该Bean,避免多实例问题:

@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {
    // 原有代码保持不变
}

额外检查点

  • 确认jwtTokenUtil.validateToken(jwt)未抛出异常(若验证失败,设置认证信息的代码不会执行)。
  • 确认请求头中的Authorization格式为Bearer {token},无拼写错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 08:45:04