Spring Security:抛出LockedException而不是BadCredentialsException,为什么?
使用Spring Security 4.0.2.RELEASE
对于使用spring-security框架的基本用户身份validation,我实现了spring-security DaoAuthenticationProvider
当用户尝试使用正确的用户名登录时, 错误的密码和用户的帐户已被锁定 ,那么我预计spring-security身份validation模块将抛出BadCredentialsException
但是它会抛出LockedException
我的问题是
- 为什么spring-security正在处理用户进行进一步的身份validation,而凭据特殊密码不正确?
- 即使用户的密码无效,在应用程序中显示“用户已锁定”的消息是否良好?
- 如何为无效密码和锁定用户设置生成/捕获
BadCredentialsException
?
任何帮助,将不胜感激。 身份validation提供程序实现代码
@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而不是BadCredentialsException,为什么?
这是因为Spring安全性将首先检查帐户是否存在且是否有效,然后检查密码。
更具体:它在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的Null-Implementation,一个用于检查所有内容的post:
-
!user.isAccountNonLocked()
-
!user.isEnabled()
-
!user.isAccountNonExpired()
-
!user.isCredentialsNonExpired()