Spring Security 6手动登录:如何正确注入AuthenticationManager?
Spring官方的手动登录示例没说明如何获取正确的AuthenticationManager,核心原因是默认情况下这个实例不会被Spring容器自动注册为可装配的Bean。下面分两种主流配置场景给出解决方案:
1. 基于WebSecurityConfigurerAdapter(旧版配置)
如果你的项目还在使用WebSecurityConfigurerAdapter(Spring Security 5.7之前的标准方式),只需在配置类中重写authenticationManagerBean()并标记为Bean即可:
@Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { // 暴露AuthenticationManager为Spring Bean @Override @Bean public AuthenticationManager authenticationManagerBean() throws Exception { return super.authenticationManagerBean(); } // 配置用户认证服务和密码编码器 @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userDetailsService()) .passwordEncoder(passwordEncoder()); } @Bean public UserDetailsService userDetailsService() { return new InMemoryUserDetailsManager( User.withUsername("user") .password(passwordEncoder().encode("pass")) .roles("USER") .build() ); } @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } }
这样配置后,就能在任意需要的类中通过@Autowired或者构造器注入AuthenticationManager。
2. 基于SecurityFilterChain(新版Spring Security 5.7+)
如果使用推荐的SecurityFilterChain配置方式,通过AuthenticationConfiguration来获取并注册AuthenticationManager:
@Configuration @EnableWebSecurity public class SecurityConfig { // 注册AuthenticationManager为Bean @Bean public AuthenticationManager authenticationManager(AuthenticationConfiguration authConfig) throws Exception { return authConfig.getAuthenticationManager(); } @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http .authorizeHttpRequests(auth -> auth.anyRequest().authenticated()) .formLogin(form -> form.permitAll()); return http.build(); } @Bean public UserDetailsService userDetailsService() { UserDetails user = User.withUsername("user") .password(passwordEncoder().encode("pass")) .roles("USER") .build(); return new InMemoryUserDetailsManager(user); } @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } }
AuthenticationConfiguration是Spring Security提供的核心配置类,它会帮你构建并返回系统实际使用的顶层ProviderManager(也就是你提到的多层级认证管理器中的主实例)。
手动登录示例代码的使用
在Service或Controller中注入AuthenticationManager后,即可执行手动登录逻辑:
@Service public class AuthService { private final AuthenticationManager authManager; // 推荐使用构造器注入 public AuthService(AuthenticationManager authManager) { this.authManager = authManager; } public Authentication login(String username, String password) { // 构造未认证的Authentication对象 Authentication unauthenticated = new UsernamePasswordAuthenticationToken(username, password); // 触发认证流程,返回已认证的Authentication return authManager.authenticate(unauthenticated); } }
调用authenticate()方法时,ProviderManager会遍历内部的AuthenticationProvider列表(比如默认的DaoAuthenticationProvider),完成用户名密码校验,校验通过后返回包含用户权限的已认证对象。
内容的提问来源于stack exchange,提问作者Lachezar Balev

