[英]Spring Security : LockedException is thrown instead of BadCredentialsException, why?
使用 Spring 安全 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而不是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()
當有多個用戶在數據庫中具有相同的憑據(名稱,email 等)時,我得到了這個異常。 無論如何這是一個測試。 在我刪除這些重復項后,一切正常。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.