Using Spring Security 4.0.2.RELEASE
For basic user authentication using spring-security framework, I implemented spring-security DaoAuthenticationProvider
When user tries to login with correct username, incorrect password and user's account is already locked, then i expected that spring-security authentication module would be throwing BadCredentialsException
But instead it throws LockedException
My Questions are
BadCredentialsException
for invalid password and locked user ?Any help would be appreciated. Authentication Provider implementation code is
@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;
}
}
}
Because Spring Security tightly integrates with the Spring Framework and other commonly used authentication mechanisms, such as HTTP basic authentication, X. 509 certificate, form-based login, and so on, it has comprehensive support for both Web applications as well as method-level security.
As of Spring Security version 5.7. 1, the default username is user and the password is randomly generated and displayed in the console (e.g. 8e557245-73e2-4286-969a-ff57fe326336 ). Ryan H. Ryan H.
Used by the default implementation of authenticationManager() to attempt to obtain an AuthenticationManager . Deprecated. Override this method to configure the HttpSecurity .
If Spring Security is on the classpath, Spring Boot automatically secures all HTTP endpoints with “basic” authentication. However, you can further customize the security settings. The first thing you need to do is add Spring Security to the classpath.
You asked:
Spring Security : LockedException is thrown instead of BadCredentialsException, why?
It is because spring security will first check that the account exist and is valid, and after that it checks the password.
More concrete: it is done in AbstractUserDetailsAuthenticationProvider.authenticate
. In an very brief description the method works this way:
user = retrieveUser(username, (UsernamePasswordAuthenticationToken) authentication);
...
preAuthenticationChecks.check(user);
additionalAuthenticationChecks(user, (UsernamePasswordAuthenticationToken) authentication);
...
postAuthenticationChecks.check(user);
retrieveUser
- load the userpreAuthenticationChecks.check(user);
- DefaultPreAuthenticationChecks
: check for locked...additionalAuthenticationChecks
- checks the passwordpostAuthenticationChecks.check(user);
- DefaultPostAuthenticationChecks
check for not expired credentialsThe good point is, that preAuthenticationChecks
and postAuthenticationChecks
are references to the Interface UserDetailsChecker
so you can change them. Just implement your own two UserDetailsChecker
, the one Null-Implementation for pre, and one for post that checks everything:
!user.isAccountNonLocked()
!user.isEnabled()
!user.isAccountNonExpired()
!user.isCredentialsNonExpired()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With