Spring Boot Security中AuthenticationManager Bean注入失败求助
解决Spring Security中AuthenticationManager找不到的问题
问题原因
你遇到的错误是因为Spring容器中不存在AuthenticationManager类型的Bean。默认情况下,Spring Security不会将这个认证管理器注册为可被@Autowired注入的Bean,所以当你在AuthController中尝试注入它时,容器找不到对应的实例。
解决方案
根据你使用的Spring Security版本,有两种配置方式可以将AuthenticationManager注册为Bean:
方式一:基于WebSecurityConfigurerAdapter(适用于Spring Security 5.x及以下)
在你的SecurityConfig类中,重写authenticationManagerBean()方法并添加@Bean注解,将认证管理器暴露给Spring容器:
import org.springframework.context.annotation.Bean; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; @Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { private final UserDetailsServiceImpl userDetailsService; public SecurityConfig(UserDetailsServiceImpl userDetailsService) { this.userDetailsService = userDetailsService; } // 配置自定义UserDetailsService和密码编码器 @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userDetailsService) .passwordEncoder(passwordEncoder()); } // 暴露AuthenticationManager为Bean @Bean @Override public AuthenticationManager authenticationManagerBean() throws Exception { return super.authenticationManagerBean(); } // 注册密码编码器Bean @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } // 配置HttpSecurity权限规则 @Override protected void configure(HttpSecurity http) throws Exception { http.csrf().disable() .authorizeRequests() .antMatchers("/auth/**").permitAll() // 允许认证接口匿名访问 .anyRequest().authenticated(); } }
方式二:基于SecurityFilterChain(适用于Spring Security 6.x及以上)
如果使用Spring Security 6+的新配置方式(不再依赖WebSecurityConfigurerAdapter),可以通过AuthenticationConfiguration获取并注册AuthenticationManager:
import org.springframework.context.annotation.Bean; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.dao.DaoAuthenticationProvider; import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.web.SecurityFilterChain; @Configuration @EnableWebSecurity public class SecurityConfig { private final UserDetailsServiceImpl userDetailsService; public SecurityConfig(UserDetailsServiceImpl userDetailsService) { this.userDetailsService = userDetailsService; } // 配置SecurityFilterChain权限规则 @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http.csrf().disable() .authorizeRequests() .antMatchers("/auth/**").permitAll() .anyRequest().authenticated(); // 配置自定义认证提供者 http.authenticationProvider(authenticationProvider()); return http.build(); } // 配置DaoAuthenticationProvider,关联UserDetailsService和密码编码器 @Bean public DaoAuthenticationProvider authenticationProvider() { DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider(); authProvider.setUserDetailsService(userDetailsService); authProvider.setPasswordEncoder(passwordEncoder()); return authProvider; } // 暴露AuthenticationManager为Bean @Bean public AuthenticationManager authenticationManager(AuthenticationConfiguration authConfig) throws Exception { return authConfig.getAuthenticationManager(); } // 注册密码编码器Bean @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } }
配置完成后,你的AuthController中@Autowired private AuthenticationManager authenticationManager;就能正常注入使用了。
内容的提问来源于stack exchange,提问作者Routfin
相关产品推荐
相关产品推荐

