SEC-1548: Added extra logging to Dao-authentication classes to clarify reasons for authentication failure (missing user vs wrong password etc.).

This commit is contained in:
Luke Taylor 2010-10-20 17:00:06 +01:00
parent d6f408e8bf
commit c458311d2d
3 changed files with 24 additions and 1 deletions

View File

@ -16,6 +16,8 @@
package org.springframework.security.authentication.dao;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.security.authentication.AccountExpiredException;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
@ -71,6 +73,9 @@ import org.springframework.util.Assert;
*/
public abstract class AbstractUserDetailsAuthenticationProvider implements AuthenticationProvider, InitializingBean,
MessageSourceAware {
protected final Log logger = LogFactory.getLog(getClass());
//~ Instance fields ================================================================================================
protected MessageSourceAccessor messages = SpringSecurityMessageSource.getAccessor();
@ -123,6 +128,8 @@ public abstract class AbstractUserDetailsAuthenticationProvider implements Authe
try {
user = retrieveUser(username, (UsernamePasswordAuthenticationToken) authentication);
} catch (UsernameNotFoundException notFound) {
logger.debug("User '" + username + "' not found");
if (hideUserNotFoundExceptions) {
throw new BadCredentialsException(messages.getMessage(
"AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"));
@ -178,7 +185,7 @@ public abstract class AbstractUserDetailsAuthenticationProvider implements Authe
* @return the successful authentication token
*/
protected Authentication createSuccessAuthentication(Object principal, Authentication authentication,
UserDetails user) {
UserDetails user) {
// Ensure we return the original credentials the user supplied,
// so subsequent attempts are successful even with encoded passwords.
// Also ensure we return the original getDetails(), so that future
@ -291,16 +298,22 @@ public abstract class AbstractUserDetailsAuthenticationProvider implements Authe
private class DefaultPreAuthenticationChecks implements UserDetailsChecker {
public void check(UserDetails user) {
if (!user.isAccountNonLocked()) {
logger.debug("User account is locked");
throw new LockedException(messages.getMessage("AbstractUserDetailsAuthenticationProvider.locked",
"User account is locked"), user);
}
if (!user.isEnabled()) {
logger.debug("User account is disabled");
throw new DisabledException(messages.getMessage("AbstractUserDetailsAuthenticationProvider.disabled",
"User is disabled"), user);
}
if (!user.isAccountNonExpired()) {
logger.debug("User account is expired");
throw new AccountExpiredException(messages.getMessage("AbstractUserDetailsAuthenticationProvider.expired",
"User account has expired"), user);
}
@ -310,6 +323,8 @@ public abstract class AbstractUserDetailsAuthenticationProvider implements Authe
private class DefaultPostAuthenticationChecks implements UserDetailsChecker {
public void check(UserDetails user) {
if (!user.isCredentialsNonExpired()) {
logger.debug("User account credentials have expired");
throw new CredentialsExpiredException(messages.getMessage(
"AbstractUserDetailsAuthenticationProvider.credentialsExpired",
"User credentials have expired"), user);

View File

@ -56,6 +56,8 @@ public class DaoAuthenticationProvider extends AbstractUserDetailsAuthentication
}
if (authentication.getCredentials() == null) {
logger.debug("Authentication failed: no credentials provided");
throw new BadCredentialsException(messages.getMessage(
"AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"),
includeDetailsObject ? userDetails : null);
@ -64,6 +66,8 @@ public class DaoAuthenticationProvider extends AbstractUserDetailsAuthentication
String presentedPassword = authentication.getCredentials().toString();
if (!passwordEncoder.isPasswordValid(userDetails.getPassword(), presentedPassword, salt)) {
logger.debug("Authentication failed: password does not match stored value");
throw new BadCredentialsException(messages.getMessage(
"AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"),
includeDetailsObject ? userDetails : null);

View File

@ -152,6 +152,8 @@ public class JdbcDaoImpl extends JdbcDaoSupport implements UserDetailsService {
List<UserDetails> users = loadUsersByUsername(username);
if (users.size() == 0) {
logger.debug("Query returned no results for user '" + username + "'");
throw new UsernameNotFoundException(
messages.getMessage("JdbcDaoImpl.notFound", new Object[]{username}, "Username {0} not found"), username);
}
@ -173,6 +175,8 @@ public class JdbcDaoImpl extends JdbcDaoSupport implements UserDetailsService {
addCustomAuthorities(user.getUsername(), dbAuths);
if (dbAuths.size() == 0) {
logger.debug("User '" + username + "' has no authorities and will be treated as 'not found'");
throw new UsernameNotFoundException(
messages.getMessage("JdbcDaoImpl.noAuthority",
new Object[] {username}, "User {0} has no GrantedAuthority"), username);