Spring Boot2.0(Spring Security5.0)下添加自定义Provider后如何获取AuthenticationManager
解决Spring Boot 2.0(Spring Security 5.0)中无法获取AuthenticationManager Bean的问题
我太懂这个坑了!当你自己重写configure(AuthenticationManagerBuilder)来添加自定义AuthenticationProvider时,Spring Security默认不会再把AuthenticationManager自动注册为Spring Bean了——这就是你拿不到它的核心原因。下面给你两个靠谱的解决方案,直接就能用:
方案一:手动暴露AuthenticationManager为Bean
在你的SecurityConfiguration类里,重写authenticationManagerBean()方法并加上@Bean注解,这样Spring就会把这个AuthenticationManager纳入容器管理,其他地方就能正常注入了。完整示例代码如下:
第一步:实现自定义AuthenticationProvider
@Component public class CustomAuthenticationProvider implements AuthenticationProvider { @Override public Authentication authenticate(Authentication authentication) throws AuthenticationException { // 这里编写你的自定义认证逻辑 String username = authentication.getName(); String password = authentication.getCredentials().toString(); // 示例:简单校验用户名密码,生成认证后的Authentication对象 if ("admin".equals(username) && "password".equals(password)) { return new UsernamePasswordAuthenticationToken(username, password, Collections.emptyList()); } else { throw new BadCredentialsException("用户名或密码错误"); } } @Override public boolean supports(Class<?> authentication) { // 指定当前Provider支持的Authentication类型,这里用最常用的用户名密码类型 return UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication); } }
第二步:修改SecurityConfiguration类
@Configuration @EnableWebSecurity public class SecurityConfiguration extends WebSecurityConfigurerAdapter { private final CustomAuthenticationProvider customAuthenticationProvider; // 推荐用构造器注入自定义Provider,避免循环依赖问题 public SecurityConfiguration(CustomAuthenticationProvider customAuthenticationProvider) { this.customAuthenticationProvider = customAuthenticationProvider; } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { // 将自定义Provider添加到认证链中 auth.authenticationProvider(customAuthenticationProvider); } // 关键:重写此方法并添加@Bean,手动暴露AuthenticationManager为Spring Bean @Bean @Override public AuthenticationManager authenticationManagerBean() throws Exception { return super.authenticationManagerBean(); } // 可选:配置HttpSecurity的权限规则(根据你的业务需求调整) @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .anyRequest().authenticated() .and() .formLogin() // 启用表单登录,可根据实际场景替换为OAuth2、JWT等 .permitAll(); } }
方案二:直接通过AuthenticationManagerBuilder构建(应急用,不推荐)
如果你只是临时需要使用AuthenticationManager,也可以直接注入AuthenticationManagerBuilder,然后调用build()方法获取实例,但这种方式每次调用都会生成新的AuthenticationManager实例,不如方案一优雅,所以优先推荐方案一。
@Service public class AuthService { private final AuthenticationManager authenticationManager; public AuthService(AuthenticationManagerBuilder authBuilder) throws Exception { this.authenticationManager = authBuilder.build(); } // 使用authenticationManager完成认证操作 public void doAuthenticate(String username, String password) { Authentication authRequest = new UsernamePasswordAuthenticationToken(username, password); Authentication authResult = authenticationManager.authenticate(authRequest); // 处理认证结果,比如存入SecurityContext等 } }
常见注意事项
- 确保自定义
AuthenticationProvider已被Spring管理(比如添加@Component注解),否则无法注入到SecurityConfiguration中。 - 不要在
authenticationManagerBean()方法中自行new AuthenticationManager,一定要调用super.authenticationManagerBean(),这样才能复用Spring Security的完整配置逻辑。 - 若遇到循环依赖问题,优先使用构造器注入,而非
@Autowired字段注入。
内容的提问来源于stack exchange,提问作者Eric B.
相关产品推荐
相关产品推荐

