Using Spring Security 4.0.2.RELEASE
对于使用 spring-security 框架的基本用户身份验证,我实现了 spring-security DaoAuthenticationProvider
当用户尝试使用正确的用户名、不正确 密码登录并且用户的帐户已被锁定 时,我预计 spring-security 身份验证模块将抛出 BadCredentialsException 但它会抛出 LockedException
我的问题是
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 检查未过期的凭据好的一点是,preAuthenticationChecks 和 postAuthenticationChecks 是对接口(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/