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

Spring Security从5升级到6后出现空指针异常求助

Spring Security 5→6.0迁移后AuthenticationManager空指针问题解决

问题重现

迁移后触发空指针异常:

java.lang.NullPointerException: Cannot invoke "org.springframework.security.authentication.AuthenticationManager.authenticate(org.springframework.security.core.Authentication)" because the return value of "org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.getAuthenticationManager()" is null
    at com.jmi.jabord.core.oauth.filter.AccessTokenAuthenticationFilter.attemptAuthentication(AccessTokenAuthenticationFilter.java:79)
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:231)
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:221)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374)
    at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:107)
    at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:93)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374)

已尝试在自定义AccessTokenAuthenticationFilter中添加如下代码,但未解决问题:

@Autowired
@Qualifier("authenticationManager")
@Override
public void setAuthenticationManager(AuthenticationManager authenticationManager) {
    super.setAuthenticationManager(authenticationManager);
}

解决方案

1. 在SecurityFilterChain中显式注入AuthenticationManager

Spring Security 6不再自动全局暴露AuthenticationManager,需在配置类中通过AuthenticationConfiguration获取并手动注入到自定义Filter:

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http, AuthenticationConfiguration authConfig) throws Exception {
        // 获取AuthenticationManager实例
        AuthenticationManager authenticationManager = authConfig.getAuthenticationManager();
        
        // 初始化自定义Filter并设置AuthenticationManager
        AccessTokenAuthenticationFilter tokenFilter = new AccessTokenAuthenticationFilter();
        tokenFilter.setAuthenticationManager(authenticationManager);
        
        // 将Filter加入过滤器链
        http.addFilterBefore(tokenFilter, UsernamePasswordAuthenticationFilter.class);
        
        // 其他安全配置...
        return http.build();
    }
}

2. 确保自定义Filter被Spring容器管理(若用@Component)

如果你的AccessTokenAuthenticationFilter标注了@Component,需直接注入容器中的实例而非新建对象:

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Autowired
    private AccessTokenAuthenticationFilter tokenFilter;

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http, AuthenticationConfiguration authConfig) throws Exception {
        AuthenticationManager authenticationManager = authConfig.getAuthenticationManager();
        tokenFilter.setAuthenticationManager(authenticationManager);
        
        http.addFilterBefore(tokenFilter, UsernamePasswordAuthenticationFilter.class);
        
        // 其他安全配置...
        return http.build();
    }
}

3. 校验AuthenticationManager的Bean名称

确认你的AuthenticationManagerBean名称确实为authenticationManager,若自定义了认证提供者,需保证配置正确:

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

如果Bean名称不是authenticationManager,需同步修改@Qualifier的参数值。

4. 通过构造方法注入AuthenticationManager(更可靠)

Spring Security 6中Filter初始化顺序可能变化,构造方法注入能避免时机问题:

@Component
public class AccessTokenAuthenticationFilter extends AbstractAuthenticationProcessingFilter {

    // 构造方法直接注入AuthenticationManager
    public AccessTokenAuthenticationFilter(AuthenticationManager authenticationManager) {
        super(new AntPathRequestMatcher("/api/**")); // 替换为你的请求匹配路径
        super.setAuthenticationManager(authenticationManager);
    }

    // 实现attemptAuthentication方法...
}

配置类中直接注入该Filter即可:

@Autowired
private AccessTokenAuthenticationFilter tokenFilter;

@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
    http.addFilterBefore(tokenFilter, UsernamePasswordAuthenticationFilter.class);
    // 其他安全配置...
    return http.build();
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 04:50:24