Spring Boot 3.0.0-M2下解决AuthenticationManager Bean缺失问题:替代已弃用WebSecurityConfigurerAdapter的方案
嘿,这个问题我最近刚处理过,自从WebSecurityConfigurerAdapter被弃用后,Spring Security 5.7+推荐用基于组件的配置方式来暴露AuthenticationManager,给你两个实用的方案,都完全避开了弃用的API:
方案1:通过AuthenticationConfiguration获取标准AuthenticationManager
这是最简洁的方式,Spring会自动帮你整合所有配置好的AuthenticationProvider,代码如下:
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.authentication.AuthenticationManager; 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.core.userdetails.UserDetailsService; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.web.SecurityFilterChain; @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; } // 配置Web安全规则(替代原WebSecurityConfigurerAdapter的configure(HttpSecurity)方法) @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http .authorizeHttpRequests(auth -> auth .requestMatchers("/auth/**").permitAll() // 允许认证接口公开访问 .anyRequest().authenticated() // 其他接口需要认证 ) .formLogin(form -> form.permitAll()); // 可根据需求配置登录方式,比如表单或OAuth2 return http.build(); } // 暴露AuthenticationManager Bean @Bean public AuthenticationManager authenticationManager(AuthenticationConfiguration authConfig) throws Exception { return authConfig.getAuthenticationManager(); } // 配置自定义认证提供者(可选,比如基于数据库的DaoAuthenticationProvider) @Bean public AuthenticationProvider authenticationProvider() { DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider(); authProvider.setUserDetailsService(userDetailsService); authProvider.setPasswordEncoder(passwordEncoder); return authProvider; } }
为什么这样可行?
AuthenticationConfiguration是Spring Security提供的核心配置类,它会自动收集你定义的所有AuthenticationProvider,构建出一个可用的AuthenticationManager,直接注入到你的AuthController即可使用。
方案2:自定义构建AuthenticationManager(适合复杂认证场景)
如果你需要更灵活地控制认证流程(比如添加多个自定义AuthenticationProvider),可以直接用AuthenticationManagerBuilder来构建:
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; 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.core.userdetails.UserDetailsService; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.web.SecurityFilterChain; @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; } // 自定义构建AuthenticationManager @Bean public AuthenticationManager authenticationManager(AuthenticationManagerBuilder authBuilder) throws Exception { // 添加基于用户详情的认证逻辑 authBuilder.userDetailsService(userDetailsService) .passwordEncoder(passwordEncoder); // 可添加多个自定义AuthenticationProvider // authBuilder.authenticationProvider(customOtpAuthProvider()); return authBuilder.build(); } // 同样需要配置Web安全规则 @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http .authorizeHttpRequests(auth -> auth .requestMatchers("/auth/login").permitAll() .anyRequest().authenticated() ); return http.build(); } }
最后:在Controller中注入使用
不管用哪种方案,你都可以直接在AuthController中注入AuthenticationManager:
@RestController @RequestMapping("/auth") public class AuthController { private final AuthenticationManager authenticationManager; // 构造注入(推荐) public AuthController(AuthenticationManager authenticationManager) { this.authenticationManager = authenticationManager; } @PostMapping("/login") public ResponseEntity<?> login(@RequestBody LoginRequest request) { // 构造认证请求 Authentication authRequest = new UsernamePasswordAuthenticationToken( request.getUsername(), request.getPassword()); // 执行认证 Authentication authResult = authenticationManager.authenticate(authRequest); // 后续生成JWT或处理登录逻辑 return ResponseEntity.ok("登录成功"); } }
内容的提问来源于stack exchange,提问作者Plugrol Huldo
相关产品推荐
相关产品推荐

