gpt4 book ai didi

java - Spring Security : LockedException is thrown instead of BadCredentialsException, 为什么?

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:22:24 24 4
gpt4 key购买 nike

Using Spring Security 4.0.2.RELEASE

对于使用 spring-security 框架的基本用户身份验证,我实现了 spring-security DaoAuthenticationProvider

当用户尝试使用正确的用户名、不正确 密码登录并且用户的帐户已被锁定 时,我预计 spring-security 身份验证模块将抛出 BadCredentialsException 但它会抛出 LockedException

我的问题是

  1. 为什么 spring-security 正在处理用户以进行进一步的身份验证,而凭据特别是密码不正确?
  2. 即使用户的密码无效,在应用程序中显示“用户已锁定”消息是否是一种好习惯?
  3. 我如何设法为无效密码和锁定用户生成/捕获 BadCredentialsException

如有任何帮助,我们将不胜感激。 Authentication Provider 实现代码为

@Component("authenticationProvider")
public class LoginAuthenticationProvider extends DaoAuthenticationProvider {

@Autowired
UserDAO userDAO;

@Autowired
@Qualifier("userDetailsService")
@Override
public void setUserDetailsService(UserDetailsService userDetailsService) {
super.setUserDetailsService(userDetailsService);
}

@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
try {
Authentication auth = super.authenticate(authentication);
// if reach here, means login success, else exception will be thrown

// reset the user attempts
userDAO.resetPasswordRetryAttempts(authentication.getName());

return auth;
} catch (BadCredentialsException ex) {
// invalid login, update user attempts
userDAO.updatePasswordRetryAttempts(authentication.getName(), PropertyUtils.getLoginAttemptsLimit());
throw ex;
} catch (LockedException ex) {
// this user is locked
throw ex;
} catch (AccountExpiredException ex) {
// this user is expired
throw ex;
} catch (Exception ex) {
ex.printStackTrace();
throw ex;
}
}

}

最佳答案

你问:

Spring Security : LockedException is thrown instead of BadCredentialsException, why?

因为spring security会先检查账号是否存在和有效,然后再检查密码。

更具体:在 AbstractUserDetailsAuthenticationProvider.authenticate 中完成。在非常简短的描述中,该方法是这样工作的:

user = retrieveUser(username, (UsernamePasswordAuthenticationToken) authentication);
...
preAuthenticationChecks.check(user);
additionalAuthenticationChecks(user, (UsernamePasswordAuthenticationToken) authentication);
...
postAuthenticationChecks.check(user);
  • retrieveUser - 加载用户
  • preAuthenticationChecks.check(user); - DefaultPreAuthenticationChecks:检查锁定...
  • additionalAuthenticationChecks - 检查密码
  • postAuthenticationChecks.check(user); - DefaultPostAuthenticationChecks 检查未过期的凭据

好的一点是,preAuthenticationCheckspostAuthenticationChecks 是对接口(interface) UserDetailsChecker 的引用,因此您可以更改它们。只需实现您自己的两个 UserDetailsChecker,一个用于 pre 的空实现,一个用于检查所有内容的 post:

  • !user.isAccountNonLocked()
  • !user.isEnabled()
  • !user.isAccountNonExpired()
  • !user.isCredentialsNonExpired()

关于java - Spring Security : LockedException is thrown instead of BadCredentialsException, 为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33969890/

24 4 0
文章推荐: java - 打印所有非零数字按升序排列的数字
文章推荐: java - 将 Java ArrayList 转换为 ArrayList