You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

添加未使用的AuthenticationProvider后Spring Security认证报错排查

问题:添加未使用的自定义AuthenticationProvider后Spring Security找不到默认Provider

原本基于Spring Boot + Spring Security的应用,使用formLogin和InMemoryUserDetailsManager运行完全正常,但添加了一个supports方法始终返回false的MyAuthenticationProvider(标注@Component)后,应用抛出No AuthenticationProvider found for org.springframework.security.authentication.UsernamePasswordAuthenticationToken异常。移除@Component注解后,应用又恢复正常。

疑问点:默认的DaoAuthenticationProvider应该负责处理UsernamePasswordAuthenticationToken,为什么仅仅添加这个“闲置”的Provider后,系统就找不到默认的DaoAuthenticationProvider了?


相关代码片段

1. 安全配置类

@Configuration
@EnableWebSecurity
public class SecurityConfiguration {
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {

        http
                .authorizeHttpRequests((authorize) -> authorize
                        .anyRequest().authenticated()
                )
                .formLogin(withDefaults());
        return http.build();
    }

    @Bean
    public InMemoryUserDetailsManager userDetailsService() {
        UserDetails user = User.withDefaultPasswordEncoder()
                .username("user")
                .password("password")
                .roles("USER")
                .build();
        return new InMemoryUserDetailsManager(user);
    }
}

2. 自定义AuthenticationProvider

@Component
public class MyAuthenticationProvider implements AuthenticationProvider {

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        throw new InsufficientAuthenticationException("Dummy");
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return false;
    }
}

原因解析

Spring Security的ProviderManager(默认的AuthenticationManager实现)会自动收集Spring容器中所有的AuthenticationProvider Bean。核心问题在于Spring Security的自动配置逻辑:

当容器中不存在任何自定义的AuthenticationProvider Bean时,自动配置类会自动创建基于UserDetailsService的DaoAuthenticationProvider,用来处理UsernamePasswordAuthenticationToken(也就是表单登录的认证令牌)。

但一旦你通过@Component将自定义的MyAuthenticationProvider注册到容器中,自动配置逻辑就会认为你要完全自定义认证流程,不再自动创建默认的DaoAuthenticationProvider。

此时ProviderManager的列表里只有你的自定义Provider,而它的supports方法始终返回false,导致遍历所有Provider时,没有任何一个能支持UsernamePasswordAuthenticationToken,最终抛出异常。


解决方法

方法1:手动注册DaoAuthenticationProvider

如果你需要保留自定义Provider,需要手动创建DaoAuthenticationProvider并注册为Bean,让它加入到ProviderManager的认证列表中:

@Bean
public DaoAuthenticationProvider daoAuthenticationProvider(InMemoryUserDetailsManager userDetailsService) {
    DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
    provider.setUserDetailsService(userDetailsService);
    // 这里使用和你创建用户时一致的密码编码器
    provider.setPasswordEncoder(PasswordEncoderFactories.createDelegatingPasswordEncoder());
    return provider;
}

方法2:移除自定义Provider的@Component注解

如果不需要这个自定义Provider,直接去掉@Component,让Spring Security自动创建默认的DaoAuthenticationProvider即可恢复正常。


内容的提问来源于stack exchange,提问作者LilRazi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 05:22:28