当前位置: 代码迷 >> 综合 >> 如何解决security中异常UsernameNotFoundException总是抛出密码错误问题
  详细解决方案

如何解决security中异常UsernameNotFoundException总是抛出密码错误问题

热度:46   发布时间:2023-09-29 19:37:00.0

使用spring security进行授权登录的时候,发现登录接口无法正常捕捉UsernameNotFoundException异常,捕捉到的一直是BadCredentialsException异常。我们的预期是:

  • UsernameNotFoundException -> 用户名错误
  • BadCredentialsException -> 密码错误

贴几个比较重要的代码:

经过步进法跟踪代码,发现问题所在,位于

AbstractUserDetailsAuthenticationProvider
public Authentication authenticate(Authentication authentication)

结论

1、loadUserByUsername方法确实抛出了UsernameNotFoundException

2、走到AbstractUserDetailsAuthenticationProvider的authenticate方法的时候,如果hideUserNotFoundExceptions = true,直接就覆盖了UsernameNotFoundException异常并抛出BadCredentialsException异常,这也就解释了,为什么总是捕捉到BadCredentialsException异常

既然已经找到了是因为hideUserNotFoundExceptions = true导致的问题,那把hideUserNotFoundExceptions = false不就完事了吗?

方案1、修改WebSecurityConfig配置,添加AuthenticationProvider Bean

@Bean
public AuthenticationProvider daoAuthenticationProvider() {DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();daoAuthenticationProvider.setUserDetailsService(userDetailsService);daoAuthenticationProvider.setPasswordEncoder(passwordEncoder());daoAuthenticationProvider.setHideUserNotFoundExceptions(false);return daoAuthenticationProvider;
}

然后配置

   @Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {auth.authenticationProvider(daoAuthenticationProvider());}

方案2、在自己的登录验证接口中不用抛出UsernameNotFoundException异常,直接抛出自定义异常,这个异常会被全局异常拦截

@Service
public class MyUserDetailService implements UserDetailsService {@Resourceprivate SysUserService sysUserService;@Resourceprivate SysRoleService sysRoleService;@Overridepublic UserDetails loadUserByUsername(String userName){SysUser sysUser = sysUserService.getByUserName(userName);if (StringUtils.isNull(sysUser)) {throw new CustomException("用户不存在");} // 查询账号角色List<String> roleList = sysRoleService.getListByUserId(sysUser.getUserId());return new UserVo(sysUser,new ArrayList<>());}
}

配置

 @Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {auth.userDetailsService(myUserDetailService).passwordEncoder(bCryptPasswordEncoder());}

 

  相关解决方案