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

Spring Security中调用AuthenticationManager.authenticate()遇StackOverflow错误

问题解决办法

问题根源

自定义AuthenticationManager Bean时,若配置不当会与Spring Security内部认证管理器形成循环依赖,调用authenticate()时触发递归调用导致栈溢出;移除该Bean后,容器中无对应实例,UserService的依赖注入会失败。

具体解决方案

1. 正确构建并暴露AuthenticationManager

不要手动创建独立的AuthenticationManager Bean,而是通过HttpSecurity的AuthenticationManagerBuilder构建认证逻辑,并将其关联到SecurityFilterChain,同时暴露为Bean:

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    private final UserDetailsService userDetailsService;
    private final PasswordEncoder passwordEncoder;

    public SecurityConfig(UserDetailsService userDetailsService, PasswordEncoder passwordEncoder) {
        this.userDetailsService = userDetailsService;
        this.passwordEncoder = passwordEncoder;
    }

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests(auth -> auth
                .anyRequest().authenticated()
            )
            .formLogin(form -> form.permitAll())
            .logout(logout -> logout.permitAll());

        // 通过AuthenticationManagerBuilder构建认证管理器
        AuthenticationManager authenticationManager = http.getSharedObject(AuthenticationManagerBuilder.class)
            .userDetailsService(userDetailsService)
            .passwordEncoder(passwordEncoder)
            .and()
            .build();

        http.authenticationManager(authenticationManager);
        return http.build();
    }

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

2. 规范UserService的依赖注入

使用构造方法注入AuthenticationManager,这是Spring推荐的方式,能避免字段注入带来的潜在依赖问题:

@Service
public class UserService {

    private final AuthenticationManager authenticationManager;

    public UserService(AuthenticationManager authenticationManager) {
        this.authenticationManager = authenticationManager;
    }

    public Authentication authenticate(String username, String password) {
        UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(username, password);
        return authenticationManager.authenticate(authToken);
    }
}

3. 排查自定义Filter的潜在影响(可选)

虽然你提到暂不考虑RequestFilter,但如果后续仍有问题,需检查该Filter是否重复调用了authenticationManager.authenticate(),避免触发额外递归。

核心说明

  • 通过HttpSecurity关联的方式构建AuthenticationManager,能避免与Spring Security内部组件形成循环依赖,从根源解决栈溢出问题。
  • 构造方法注入可确保依赖在Bean初始化时就被注入,减少依赖注入相关的异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 20:37:38