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
相关产品推荐
相关产品推荐

