解决 Spring Security 抛出 UsernameNotFoundException 异常后,始终都是 Bad credentials 的问题。

遇到的问题

先说下我的需求:当用户输入不存在的用户名进行登录时,返回账户不存在的提示。

在做项目的时候使用 Spring Security 作用户登录和授权,定义了 UserDetailsService 的实现类,在这个实现类的 loadUserByUsername(String username) 方法下,我是先判断 username 账户是否存在,如果不存在就直接抛出异常,告诉用户账户不存在的信息。抛出异常代码如下:

if (user == null) {
	throw new UsernameNotFoundException("账户不存在!");
}

之后我又定义了一个 AbstractAuthenticationProcessingFilter 的实现类作为登录的过滤器,重写该实现类的 unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed) 在登录失败的情况下会执行这个方法,failed 其实就一个异常对象,通过 failed.getMessage() 就可以看到抛出的异常信息。

但是我发现通过 throw new UsernameNotFoundException("账户不存在!"); 抛出的异常信息,在 failed.getMessage() 中,得到的却是 Bad credentials
解决 Spring Security 抛出 UsernameNotFoundException 异常后,始终都是 Bad credentials 的问题。_第1张图片
后来通过参考网上的文章了解到,这是因为 AbstractUserDetailsAuthenticationProvider 类的 authenticate() 方法中 hideUserNotFoundExceptions = true 的原因,想要了解更详细的内容,可以参考其他的文章,我在这里记录一下解决方法。

方法一

当用户不存在的时候使用 BadCredentialsException 异常去处理。关键代码如下:

if (user == null) {
	throw new BadCredentialsException("账户不存在!");
}

这样就已经解决了问题效果如下:
解决 Spring Security 抛出 UsernameNotFoundException 异常后,始终都是 Bad credentials 的问题。_第2张图片

方法二

自定义一个异常类,这个异常类继承 AuthenticationException,异常类代码如下:

public class MyUsernameNotFoundException extends AuthenticationException {
    public MyUsernameNotFoundException(String msg) {
        super(msg);
    }
}

当用户不存在的时候抛出我们自定义的异常类。

if (user == null) {
	throw new MyUsernameNotFoundException("账户不存在!");
}

这样也能解决问题。效果如下:
解决 Spring Security 抛出 UsernameNotFoundException 异常后,始终都是 Bad credentials 的问题。_第3张图片

你可能感兴趣的:(Spring,Security,spring,java,后端)