Pull functionality for hiding UsernameNotFoundException's up into AbstractUserDetailsAuthenticationProvider.
This commit is contained in:
parent
929b08c085
commit
9554dc50bc
|
@ -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 <code>AbstractUserDetailsAuthenticationProvider</code>
|
||||
* throws a <code>BadCredentialsException</code> if a username is
|
||||
* not found or the password is incorrect. Setting this property to
|
||||
* <code>false</code> will cause
|
||||
* <code>UsernameNotFoundException</code>s to be thrown instead for
|
||||
* the former. Note this is considered less secure than throwing
|
||||
* <code>BadCredentialsException</code> for both exceptions.
|
||||
*
|
||||
* @param hideUserNotFoundExceptions set to <code>false</code> if you
|
||||
* wish <code>UsernameNotFoundException</code>s to be thrown
|
||||
* instead of the non-specific
|
||||
* <code>BadCredentialsException</code> (defaults to
|
||||
* <code>true</code>)
|
||||
*/
|
||||
public void setHideUserNotFoundExceptions(
|
||||
boolean hideUserNotFoundExceptions) {
|
||||
this.hideUserNotFoundExceptions = hideUserNotFoundExceptions;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 <code>DaoAuthenticationProvider</code> throws a
|
||||
* <code>BadCredentialsException</code> if a username is not found or
|
||||
* the password is incorrect. Setting this property to
|
||||
* <code>false</code> will cause
|
||||
* <code>UsernameNotFoundException</code>s to be thrown instead for
|
||||
* the former. Note this is considered less secure than throwing
|
||||
* <code>BadCredentialsException</code> for both exceptions.
|
||||
*
|
||||
* @param hideUserNotFoundExceptions set to <code>false</code> if you
|
||||
* wish <code>UsernameNotFoundException</code>s to be thrown
|
||||
* instead of the non-specific
|
||||
* <code>BadCredentialsException</code> (defaults to
|
||||
* <code>true</code>)
|
||||
*/
|
||||
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.
|
||||
* <code>null</code> is a valid value, meaning the
|
||||
* <code>DaoAuthenticationProvider</code> will present
|
||||
* <code>null</code> to the relevant <code>PasswordEncoder</code>.
|
||||
*
|
||||
* @param saltSource to use when attempting to decode passwords via the
|
||||
* <code>PasswordEncoder</code>
|
||||
*/
|
||||
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.
|
||||
* <code>null</code> is a valid value, meaning the
|
||||
* <code>DaoAuthenticationProvider</code> will present
|
||||
* <code>null</code> to the relevant <code>PasswordEncoder</code>.
|
||||
*
|
||||
* @param saltSource to use when attempting to decode passwords via the
|
||||
* <code>PasswordEncoder</code>
|
||||
*/
|
||||
public void setSaltSource(SaltSource saltSource) {
|
||||
this.saltSource = saltSource;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue