Spring Boot 3.1.2登录报错:No AuthenticationProvider found问题排查
问题背景
Spring Boot版本:3.1.2
开发集成Spring Security的简单应用时,表单登录触发报错:
No AuthenticationProvider found for org.springframework.security.authentication.UsernamePasswordAuthenticationToken
原本以为Spring Boot会默认实例化DaoAuthenticationProvider,自动加载自定义的UserDetailsService和PasswordEncoder Bean,不清楚为何出现该错误。
配置代码
@Configuration public class DemoSecurityConfig { @Bean public PasswordEncoder passwordEncoder() { var encoders = new HashMap<String, PasswordEncoder>( Map.of("bcrypt",new BCryptPasswordEncoder(), "noop", NoOpPasswordEncoder.getInstance()) ); var e = new DelegatingPasswordEncoder("noop", encoders); return e; } @Bean public UserDetailsService userDetailsManager() { UserDetails susan = User.builder() .username("susan") .password("{noop}test123") .roles("EMPLOYEE", "MANAGER", "ADMIN") .build(); return new InMemoryUserDetailsManager(susan); } @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http.authorizeHttpRequests(configurer -> configurer.requestMatchers("/css/**").permitAll() .anyRequest().authenticated() ); http.formLogin(Customizer.withDefaults()); http.csrf(csrf -> csrf.disable()); return http.build(); } }
错误截图
问题原因及修复方案
核心原因
你手动定义了SecurityFilterChain Bean,但没有显式将自定义的UserDetailsService和PasswordEncoder绑定到Spring Security的认证流程中。在Spring Security 6.x(对应Spring Boot 3.x)里,一旦自定义了SecurityFilterChain,默认不会自动注册DaoAuthenticationProvider,导致系统找不到处理UsernamePasswordAuthenticationToken的认证提供者。
修复方案
方案1:在SecurityFilterChain中直接关联Bean
修改filterChain方法,注入你的UserDetailsService和PasswordEncoder,并绑定到HttpSecurity配置:
@Bean public SecurityFilterChain filterChain(HttpSecurity http, UserDetailsService userDetailsManager, PasswordEncoder passwordEncoder) throws Exception { http.authorizeHttpRequests(configurer -> configurer.requestMatchers("/css/**").permitAll() .anyRequest().authenticated() ) .formLogin(Customizer.withDefaults()) // 绑定自定义的用户详情服务和密码编码器 .userDetailsService(userDetailsManager) .passwordEncoder(passwordEncoder); http.csrf(csrf -> csrf.disable()); return http.build(); }
方案2:注册AuthenticationManager Bean
添加AuthenticationManager的Bean定义,让Spring Security自动关联你的UserDetailsService和PasswordEncoder:
@Bean public AuthenticationManager authenticationManager(AuthenticationConfiguration authConfig) throws Exception { return authConfig.getAuthenticationManager(); }
补充说明
只有当你没有自定义SecurityFilterChain时,Spring Boot的自动配置才会帮你注册DaoAuthenticationProvider并关联相关Bean。一旦自定义了SecurityFilterChain,就需要手动完成认证组件的绑定,否则会出现找不到认证提供者的错误。
内容的提问来源于stack exchange,提问作者Nick Wills

