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 c37520a0b1..9e6ba3c139 100644 --- a/core/src/main/java/org/acegisecurity/providers/dao/AbstractUserDetailsAuthenticationProvider.java +++ b/core/src/main/java/org/acegisecurity/providers/dao/AbstractUserDetailsAuthenticationProvider.java @@ -31,6 +31,7 @@ import org.acegisecurity.providers.dao.cache.NullUserCache; import org.acegisecurity.userdetails.UserDetails; import org.acegisecurity.userdetails.UserDetailsService; import org.acegisecurity.userdetails.UsernameNotFoundException; +import org.acegisecurity.userdetails.UserDetailsChecker; import org.springframework.beans.factory.InitializingBean; @@ -66,13 +67,15 @@ import org.springframework.util.Assert; * @version $Id$ */ public abstract class AbstractUserDetailsAuthenticationProvider implements AuthenticationProvider, InitializingBean, - MessageSourceAware { + MessageSourceAware { //~ Instance fields ================================================================================================ protected MessageSourceAccessor messages = AcegiMessageSource.getAccessor(); private UserCache userCache = new NullUserCache(); private boolean forcePrincipalAsString = false; protected boolean hideUserNotFoundExceptions = true; + private UserDetailsChecker preAuthenticationChecks = new DefaultPreAuthenticationChecks(); + private UserDetailsChecker postAuthenticationChecks = new DefaultPostAuthenticationChecks(); //~ Methods ======================================================================================================== @@ -129,20 +132,7 @@ public abstract class AbstractUserDetailsAuthenticationProvider implements Authe Assert.notNull(user, "retrieveUser returned null - a violation of the interface contract"); } - if (!user.isAccountNonLocked()) { - throw new LockedException(messages.getMessage("AbstractUserDetailsAuthenticationProvider.locked", - "User account is locked")); - } - - if (!user.isEnabled()) { - throw new DisabledException(messages.getMessage("AbstractUserDetailsAuthenticationProvider.disabled", - "User is disabled")); - } - - if (!user.isAccountNonExpired()) { - throw new AccountExpiredException(messages.getMessage("AbstractUserDetailsAuthenticationProvider.expired", - "User account has expired")); - } + preAuthenticationChecks.check(user); // This check must come here, as we don't want to tell users // about account status unless they presented the correct credentials @@ -160,10 +150,7 @@ public abstract class AbstractUserDetailsAuthenticationProvider implements Authe } } - if (!user.isCredentialsNonExpired()) { - throw new CredentialsExpiredException(messages.getMessage( - "AbstractUserDetailsAuthenticationProvider.credentialsExpired", "User credentials have expired")); - } + postAuthenticationChecks.check(user); if (!cacheWasUsed) { this.userCache.putUserInCache(user); @@ -275,7 +262,53 @@ public abstract class AbstractUserDetailsAuthenticationProvider implements Authe this.userCache = userCache; } + protected UserDetailsChecker getPreAuthenticationChecks() { + return preAuthenticationChecks; + } + + public void setPreAuthenticationChecks(UserDetailsChecker preAuthenticationChecks) { + this.preAuthenticationChecks = preAuthenticationChecks; + } + + protected UserDetailsChecker getPostAuthenticationChecks() { + return postAuthenticationChecks; + } + + public void setPostAuthenticationChecks(UserDetailsChecker postAuthenticationChecks) { + this.postAuthenticationChecks = postAuthenticationChecks; + } + public boolean supports(Class authentication) { return (UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication)); } + + private class DefaultPreAuthenticationChecks implements UserDetailsChecker { + public void check(UserDetails user) { + if (!user.isAccountNonLocked()) { + throw new LockedException(messages.getMessage("AbstractUserDetailsAuthenticationProvider.locked", + "User account is locked")); + } + + if (!user.isEnabled()) { + throw new DisabledException(messages.getMessage("AbstractUserDetailsAuthenticationProvider.disabled", + "User is disabled")); + } + + if (!user.isAccountNonExpired()) { + throw new AccountExpiredException(messages.getMessage("AbstractUserDetailsAuthenticationProvider.expired", + "User account has expired")); + } + + } + } + + private class DefaultPostAuthenticationChecks implements UserDetailsChecker { + public void check(UserDetails user) { + if (!user.isCredentialsNonExpired()) { + throw new CredentialsExpiredException(messages.getMessage( + "AbstractUserDetailsAuthenticationProvider.credentialsExpired", "User credentials have expired")); + } + + } + } } diff --git a/core/src/main/java/org/acegisecurity/userdetails/UserDetailsChecker.java b/core/src/main/java/org/acegisecurity/userdetails/UserDetailsChecker.java new file mode 100644 index 0000000000..fda474e577 --- /dev/null +++ b/core/src/main/java/org/acegisecurity/userdetails/UserDetailsChecker.java @@ -0,0 +1,10 @@ +package org.acegisecurity.userdetails; + +/** + * @author Luke Taylor + * @version $Id$ + * @since 1.0.7 + */ +public interface UserDetailsChecker { + void check(UserDetails toCheck); +} diff --git a/core/src/main/java/org/acegisecurity/userdetails/checker/AccountStatusUserDetailsChecker.java b/core/src/main/java/org/acegisecurity/userdetails/checker/AccountStatusUserDetailsChecker.java new file mode 100644 index 0000000000..f55bc3b007 --- /dev/null +++ b/core/src/main/java/org/acegisecurity/userdetails/checker/AccountStatusUserDetailsChecker.java @@ -0,0 +1,42 @@ +package org.acegisecurity.userdetails.checker; + + +import org.springframework.context.support.MessageSourceAccessor; + +import org.acegisecurity.LockedException; +import org.acegisecurity.CredentialsExpiredException; +import org.acegisecurity.AccountExpiredException; +import org.acegisecurity.DisabledException; +import org.acegisecurity.AcegiMessageSource; +import org.acegisecurity.userdetails.UserDetailsChecker; +import org.acegisecurity.userdetails.UserDetails; + +/** + * @author Luke Taylor + * @version $Id$ + * @since 1.0.7 + */ +public class AccountStatusUserDetailsChecker implements UserDetailsChecker { + + protected MessageSourceAccessor messages = AcegiMessageSource.getAccessor(); + + public void check(UserDetails user) { + if (!user.isAccountNonLocked()) { + throw new LockedException(messages.getMessage("UserDetailsService.locked", "User account is locked")); + } + + if (!user.isEnabled()) { + throw new DisabledException(messages.getMessage("UserDetailsService.disabled", "User is disabled")); + } + + if (!user.isAccountNonExpired()) { + throw new AccountExpiredException(messages.getMessage("UserDetailsService.expired", + "User account has expired")); + } + + if (!user.isCredentialsNonExpired()) { + throw new CredentialsExpiredException(messages.getMessage("UserDetailsService.credentialsExpired", + "User credentials have expired")); + } + } +} diff --git a/releasebuild.sh b/releasebuild.sh index 1c51026586..40dbd451de 100644 --- a/releasebuild.sh +++ b/releasebuild.sh @@ -120,12 +120,12 @@ fi pushd $SITE_DIR -find . -maxdepth 2 -mindepth 2 -name "*.html" | xargs perl -i -p -e 's#\./css/#\.\./css/#;' \ +find . -maxdepth 2 -mindepth 2 -name "*.html" | xargs perl -i -p -e 's#"\./css/#"\.\./css/#;' \ -e 's/Maven Surefire Report/Unit Tests/;' \ -e 's/Cobertura Test Coverage/Test Coverage/;' \ -e 's/A successful project.*greatly appreciated\.//;' -find . -maxdepth 3 -mindepth 3 -name "*.html" | xargs perl -i -p -e 's#\./css/#\.\./\.\./css/#;' +find . -maxdepth 3 -mindepth 3 -name "*.html" | xargs perl -i -p -e 's#"\./css/#"\.\./\.\./css/#;' popd