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

Spring Boot中UsernameNotFoundException被转为BadCredentialsException如何解决

问题根因

Spring Security 内置的DaoAuthenticationProvider默认开启了hideUserNotFoundExceptions配置,默认值为true。该设计初衷是避免攻击者通过接口返回差异枚举系统存在的用户名,所以会把所有身份校验阶段抛出的异常(包括你自定义的UsernameNotFoundException)统一包装为BadCredentialsException返回,因此你在失败处理器中拿到的是转换后的异常。

解决方法

你需要自定义DaoAuthenticationProvider实例,关闭异常隐藏配置,再将该实例注册到认证管理器中即可,具体实现如下:

  1. 声明自定义DaoAuthenticationProvider Bean
@Bean
public DaoAuthenticationProvider customDaoAuthenticationProvider(UserDetailsService userDetailsService, PasswordEncoder passwordEncoder) {
    DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
    // 关联你自己实现的用户查询逻辑
    provider.setUserDetailsService(userDetailsService);
    provider.setPasswordEncoder(passwordEncoder);
    // 关闭用户不存在异常的隐藏配置
    provider.setHideUserNotFoundExceptions(false);
    return provider;
}
  1. 将自定义Provider注册到认证管理器
    在你的Spring Security配置类中,将上面声明的Provider加入认证管理器配置:
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private DaoAuthenticationProvider customDaoAuthenticationProvider;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(customDaoAuthenticationProvider);
    }

    // 其余你的原有Security配置保持不变
}

配置完成后,你在CustomAuthenticationFailureHandler中就能直接获取到原始抛出的UsernameNotFoundException,可以根据异常类型返回对应提示。

注意:关闭异常隐藏后,攻击者可通过接口返回信息判断用户名是否存在,存在用户枚举的安全风险,对外提供服务的场景请谨慎开启该配置。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 05:15:04