diff --git a/core/src/main/java/org/acegisecurity/providers/dao/AbstractUserDetailsAuthenticationProvider.java b/core/src/main/java/org/acegisecurity/providers/dao/AbstractUserDetailsAuthenticationProvider.java index e5640d4cff..4d91c536ce 100644 --- a/core/src/main/java/org/acegisecurity/providers/dao/AbstractUserDetailsAuthenticationProvider.java +++ b/core/src/main/java/org/acegisecurity/providers/dao/AbstractUserDetailsAuthenticationProvider.java @@ -22,11 +22,13 @@ import org.acegisecurity.AuthenticationException; import org.acegisecurity.CredentialsExpiredException; import org.acegisecurity.DisabledException; import org.acegisecurity.LockedException; +import org.acegisecurity.BadCredentialsException; import org.acegisecurity.providers.AuthenticationProvider; import org.acegisecurity.providers.UsernamePasswordAuthenticationToken; import org.acegisecurity.providers.dao.cache.NullUserCache; import org.acegisecurity.userdetails.UserDetails; import org.acegisecurity.userdetails.UserDetailsService; +import org.acegisecurity.userdetails.UsernameNotFoundException; import org.springframework.beans.factory.InitializingBean; import org.springframework.context.MessageSource; import org.springframework.context.MessageSourceAware; @@ -73,6 +75,7 @@ public abstract class AbstractUserDetailsAuthenticationProvider protected MessageSourceAccessor messages = AcegiMessageSource.getAccessor(); private UserCache userCache = new NullUserCache(); private boolean forcePrincipalAsString = false; + protected boolean hideUserNotFoundExceptions = true; //~ Methods ================================================================ @@ -123,8 +126,21 @@ public abstract class AbstractUserDetailsAuthenticationProvider if (user == null) { cacheWasUsed = false; - user = retrieveUser(username, + + try { + user = retrieveUser(username, (UsernamePasswordAuthenticationToken) authentication); + + } catch (UsernameNotFoundException notFound) { + if (hideUserNotFoundExceptions) { + throw new BadCredentialsException(messages.getMessage( + "AbstractUserDetailsAuthenticationProvider.badCredentials", + "Bad credentials")); + } else { + throw notFound; + } + } + Assert.notNull(user, "retrieveUser returned null - a violation of the interface contract"); } @@ -292,4 +308,28 @@ public abstract class AbstractUserDetailsAuthenticationProvider public boolean supports(Class authentication) { return (UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication)); } + + public boolean isHideUserNotFoundExceptions() { + return hideUserNotFoundExceptions; + } + + /** + * By default the AbstractUserDetailsAuthenticationProvider + * throws a BadCredentialsException if a username is + * not found or the password is incorrect. Setting this property to + * false will cause + * UsernameNotFoundExceptions to be thrown instead for + * the former. Note this is considered less secure than throwing + * BadCredentialsException for both exceptions. + * + * @param hideUserNotFoundExceptions set to false if you + * wish UsernameNotFoundExceptions to be thrown + * instead of the non-specific + * BadCredentialsException (defaults to + * true) + */ + public void setHideUserNotFoundExceptions( + boolean hideUserNotFoundExceptions) { + this.hideUserNotFoundExceptions = hideUserNotFoundExceptions; + } } diff --git a/core/src/main/java/org/acegisecurity/providers/dao/DaoAuthenticationProvider.java b/core/src/main/java/org/acegisecurity/providers/dao/DaoAuthenticationProvider.java index da8a20a034..b79c955494 100644 --- a/core/src/main/java/org/acegisecurity/providers/dao/DaoAuthenticationProvider.java +++ b/core/src/main/java/org/acegisecurity/providers/dao/DaoAuthenticationProvider.java @@ -35,6 +35,9 @@ import org.springframework.util.Assert; /** * An {@link AuthenticationProvider} implementation that retrieves user details * from an {@link UserDetailsService}. + * + * @author Ben Alex + * @version $Id$ */ public class DaoAuthenticationProvider extends AbstractUserDetailsAuthenticationProvider { @@ -43,7 +46,6 @@ public class DaoAuthenticationProvider private UserDetailsService userDetailsService; private PasswordEncoder passwordEncoder = new PlaintextPasswordEncoder(); private SaltSource saltSource; - private boolean hideUserNotFoundExceptions = true; //~ Methods ================================================================ @@ -81,83 +83,51 @@ public class DaoAuthenticationProvider return saltSource; } - public boolean isHideUserNotFoundExceptions() { - return hideUserNotFoundExceptions; - } - protected final UserDetails retrieveUser(String username, - UsernamePasswordAuthenticationToken authentication) + UsernamePasswordAuthenticationToken authentication) throws AuthenticationException { UserDetails loadedUser; try { loadedUser = this.userDetailsService.loadUserByUsername(username); - } catch (UsernameNotFoundException notFound) { - if (hideUserNotFoundExceptions) { - throw new BadCredentialsException(messages.getMessage( - "AbstractUserDetailsAuthenticationProvider.badCredentials", - "Bad credentials")); - } else { - throw notFound; - } } catch (DataAccessException repositoryProblem) { - throw new AuthenticationServiceException(repositoryProblem - .getMessage(), repositoryProblem); - } + throw new AuthenticationServiceException( + repositoryProblem.getMessage(), repositoryProblem ); + } - if (loadedUser == null) { - throw new AuthenticationServiceException( + if (loadedUser == null) { + throw new AuthenticationServiceException( "AuthenticationDao returned null, which is an interface contract violation"); - } - - return loadedUser; } - public void setUserDetailsService(UserDetailsService authenticationDao) { - this.userDetailsService = authenticationDao; - } - - /** - * By default the DaoAuthenticationProvider throws a - * BadCredentialsException if a username is not found or - * the password is incorrect. Setting this property to - * false will cause - * UsernameNotFoundExceptions to be thrown instead for - * the former. Note this is considered less secure than throwing - * BadCredentialsException for both exceptions. - * - * @param hideUserNotFoundExceptions set to false if you - * wish UsernameNotFoundExceptions to be thrown - * instead of the non-specific - * BadCredentialsException (defaults to - * true) - */ - public void setHideUserNotFoundExceptions( - boolean hideUserNotFoundExceptions) { - this.hideUserNotFoundExceptions = hideUserNotFoundExceptions; - } - - /** - * Sets the PasswordEncoder instance to be used to encode and validate - * passwords. If not set, {@link PlaintextPasswordEncoder} will be - * used by default. - * - * @param passwordEncoder The passwordEncoder to use - */ - public void setPasswordEncoder(PasswordEncoder passwordEncoder) { - this.passwordEncoder = passwordEncoder; - } - - /** - * The source of salts to use when decoding passwords. - * null is a valid value, meaning the - * DaoAuthenticationProvider will present - * null to the relevant PasswordEncoder. - * - * @param saltSource to use when attempting to decode passwords via the - * PasswordEncoder - */ - public void setSaltSource(SaltSource saltSource) { - this.saltSource = saltSource; - } + return loadedUser; } + + public void setUserDetailsService(UserDetailsService authenticationDao) { + this.userDetailsService = authenticationDao; + } + + /** + * Sets the PasswordEncoder instance to be used to encode and validate + * passwords. If not set, {@link PlaintextPasswordEncoder} will be + * used by default. + * + * @param passwordEncoder The passwordEncoder to use + */ + public void setPasswordEncoder(PasswordEncoder passwordEncoder) { + this.passwordEncoder = passwordEncoder; + } + + /** + * The source of salts to use when decoding passwords. + * null is a valid value, meaning the + * DaoAuthenticationProvider will present + * null to the relevant PasswordEncoder. + * + * @param saltSource to use when attempting to decode passwords via the + * PasswordEncoder + */ + public void setSaltSource(SaltSource saltSource) { + this.saltSource = saltSource; + } +}