Spring Security授权服务器AuthenticationManager注入失败报错求助
针对你遇到的authenticationManager cannot be null错误,以及添加http.authenticationManager(authenticationManager);时的符号解析问题,结合你使用的Authorization Server 1.4.1、Spring Boot 3.4.2、Java 17版本,可按以下步骤解决:
核心原因
Spring Authorization Server 1.x 配合Spring Boot 3时,默认不会自动将AuthenticationManager注册到Spring上下文,授权服务器流程需要该实例完成用户认证,因此需显式配置并暴露该Bean。
具体解决步骤
配置UserDetailsService Bean
授权服务器需要用户信息支撑认证流程,先定义一个UserDetailsService(示例用内存用户,实际可替换为数据库实现):@Bean public UserDetailsService userDetailsService() { UserDetails user = User.withUsername("user") .password("{bcrypt}$2a$10$GRLdNijSQMUvl/au9ofL.eDwmoohzzS7.rmNSJZ.0FxO/BTk76klW") .roles("USER") .build(); return new InMemoryUserDetailsManager(user); }暴露AuthenticationManager Bean
通过AuthenticationConfiguration获取并注册AuthenticationManager到上下文:@Bean public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception { return authenticationConfiguration.getAuthenticationManager(); }在授权服务器FilterChain中注入并设置AuthenticationManager
在authorizationServerSecurityFilterChain方法中注入已注册的AuthenticationManager,并绑定到HttpSecurity:@Bean @Order(1) // 确保授权服务器FilterChain优先级高于资源服务器 public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http, AuthenticationManager authenticationManager) throws Exception { OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http); // 绑定authenticationManager到HttpSecurity http.authenticationManager(authenticationManager); // 启用OIDC(可选,根据需求调整) http.getConfigurer(OAuth2AuthorizationServerConfigurer.class) .oidc(Customizer.withDefaults()); return http.build(); }添加资源服务器FilterChain(可选)
如果同时需要保护API资源,可添加普通的资源服务器FilterChain:@Bean @Order(2) public SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception { http.authorizeHttpRequests(authorize -> authorize .anyRequest().authenticated() ) .formLogin(Customizer.withDefaults()); return http.build(); }
完整SecurityConfig示例
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.AuthenticationConfiguration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.provisioning.InMemoryUserDetailsManager; import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.config.Customizer; import org.springframework.security.oauth2.server.authorization.config.annotation.web.configuration.OAuth2AuthorizationServerConfiguration; import org.springframework.security.oauth2.server.authorization.config.annotation.web.configurers.OAuth2AuthorizationServerConfigurer; @Configuration @EnableWebSecurity public class SecurityConfig { @Bean public UserDetailsService userDetailsService() { UserDetails user = User.withUsername("user") .password(passwordEncoder().encode("password")) .roles("USER") .build(); return new InMemoryUserDetailsManager(user); } @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } @Bean public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception { return authenticationConfiguration.getAuthenticationManager(); } @Bean @Order(1) public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http, AuthenticationManager authenticationManager) throws Exception { OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http); http.authenticationManager(authenticationManager); http.getConfigurer(OAuth2AuthorizationServerConfigurer.class) .oidc(Customizer.withDefaults()); return http.build(); } @Bean @Order(2) public SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception { http.authorizeHttpRequests(authorize -> authorize .anyRequest().authenticated() ) .formLogin(Customizer.withDefaults()); return http.build(); } }
内容的提问来源于stack exchange,提问作者user3324336

