SEC-536: Introduced UserDetailsChecker strategy to extract code for checking status of accounts and allowing variation in pre/post authentication checks made by AbstractUserDetailsAuthenticationProvider
This commit is contained in:
parent
da90b81e16
commit
5e204e23f3
|
@ -5,7 +5,6 @@ import org.springframework.security.ui.preauth.x509.X509PreAuthenticatedProcessi
|
||||||
import org.springframework.security.ui.preauth.x509.SubjectDnX509PrincipalExtractor;
|
import org.springframework.security.ui.preauth.x509.SubjectDnX509PrincipalExtractor;
|
||||||
import org.springframework.security.providers.preauth.PreAuthenticatedAuthenticationProvider;
|
import org.springframework.security.providers.preauth.PreAuthenticatedAuthenticationProvider;
|
||||||
import org.springframework.security.providers.preauth.UserDetailsByNameServiceWrapper;
|
import org.springframework.security.providers.preauth.UserDetailsByNameServiceWrapper;
|
||||||
import org.springframework.security.userdetails.decorator.StatusCheckingUserDetailsService;
|
|
||||||
import org.springframework.beans.factory.xml.BeanDefinitionParser;
|
import org.springframework.beans.factory.xml.BeanDefinitionParser;
|
||||||
import org.springframework.beans.factory.xml.ParserContext;
|
import org.springframework.beans.factory.xml.ParserContext;
|
||||||
import org.springframework.beans.factory.config.BeanDefinition;
|
import org.springframework.beans.factory.config.BeanDefinition;
|
||||||
|
@ -52,12 +51,9 @@ public class X509BeanDefinitionParser implements BeanDefinitionParser {
|
||||||
String userServiceRef = element.getAttribute(ATT_USER_SERVICE_REF);
|
String userServiceRef = element.getAttribute(ATT_USER_SERVICE_REF);
|
||||||
|
|
||||||
if (StringUtils.hasText(userServiceRef)) {
|
if (StringUtils.hasText(userServiceRef)) {
|
||||||
RootBeanDefinition statusCheckingUserService = new RootBeanDefinition(StatusCheckingUserDetailsService.class);
|
|
||||||
statusCheckingUserService.setSource(source);
|
|
||||||
statusCheckingUserService.getConstructorArgumentValues().addIndexedArgumentValue(0, new RuntimeBeanReference(userServiceRef));
|
|
||||||
RootBeanDefinition preAuthUserService = new RootBeanDefinition(UserDetailsByNameServiceWrapper.class);
|
RootBeanDefinition preAuthUserService = new RootBeanDefinition(UserDetailsByNameServiceWrapper.class);
|
||||||
preAuthUserService.setSource(source);
|
preAuthUserService.setSource(source);
|
||||||
preAuthUserService.getPropertyValues().addPropertyValue("userDetailsService", statusCheckingUserService);
|
preAuthUserService.getPropertyValues().addPropertyValue("userDetailsService", new RuntimeBeanReference(userServiceRef));
|
||||||
provider.getPropertyValues().addPropertyValue("preAuthenticatedUserDetailsService", preAuthUserService);
|
provider.getPropertyValues().addPropertyValue("preAuthenticatedUserDetailsService", preAuthUserService);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,7 @@ import org.springframework.security.providers.dao.cache.NullUserCache;
|
||||||
import org.springframework.security.userdetails.UserDetails;
|
import org.springframework.security.userdetails.UserDetails;
|
||||||
import org.springframework.security.userdetails.UserDetailsService;
|
import org.springframework.security.userdetails.UserDetailsService;
|
||||||
import org.springframework.security.userdetails.UsernameNotFoundException;
|
import org.springframework.security.userdetails.UsernameNotFoundException;
|
||||||
|
import org.springframework.security.userdetails.UserDetailsChecker;
|
||||||
|
|
||||||
import org.springframework.beans.factory.InitializingBean;
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
|
||||||
|
@ -56,8 +57,8 @@ import org.springframework.util.Assert;
|
||||||
* and <code>UserDetails</code> implementations provide additional flexibility, by default a <code>UserDetails</code>
|
* and <code>UserDetails</code> implementations provide additional flexibility, by default a <code>UserDetails</code>
|
||||||
* is returned. To override this
|
* is returned. To override this
|
||||||
* default, set the {@link #setForcePrincipalAsString} to <code>true</code>.
|
* default, set the {@link #setForcePrincipalAsString} to <code>true</code>.
|
||||||
* </p>
|
* <p>
|
||||||
* <p>Caching is handled via the <code>UserDetails</code> object being placed in the {@link UserCache}. This
|
* Caching is handled via the <code>UserDetails</code> object being placed in the {@link UserCache}. This
|
||||||
* ensures that subsequent requests with the same username can be validated without needing to query the {@link
|
* ensures that subsequent requests with the same username can be validated without needing to query the {@link
|
||||||
* UserDetailsService}. It should be noted that if a user appears to present an incorrect password, the {@link
|
* UserDetailsService}. It should be noted that if a user appears to present an incorrect password, the {@link
|
||||||
* UserDetailsService} will be queried to confirm the most up-to-date password was used for comparison.</p>
|
* UserDetailsService} will be queried to confirm the most up-to-date password was used for comparison.</p>
|
||||||
|
@ -66,13 +67,15 @@ import org.springframework.util.Assert;
|
||||||
* @version $Id$
|
* @version $Id$
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractUserDetailsAuthenticationProvider implements AuthenticationProvider, InitializingBean,
|
public abstract class AbstractUserDetailsAuthenticationProvider implements AuthenticationProvider, InitializingBean,
|
||||||
MessageSourceAware {
|
MessageSourceAware {
|
||||||
//~ Instance fields ================================================================================================
|
//~ Instance fields ================================================================================================
|
||||||
|
|
||||||
protected MessageSourceAccessor messages = SpringSecurityMessageSource.getAccessor();
|
protected MessageSourceAccessor messages = SpringSecurityMessageSource.getAccessor();
|
||||||
private UserCache userCache = new NullUserCache();
|
private UserCache userCache = new NullUserCache();
|
||||||
private boolean forcePrincipalAsString = false;
|
private boolean forcePrincipalAsString = false;
|
||||||
protected boolean hideUserNotFoundExceptions = true;
|
protected boolean hideUserNotFoundExceptions = true;
|
||||||
|
private UserDetailsChecker preAuthenticationChecks = new DefaultPreAuthenticationChecks();
|
||||||
|
private UserDetailsChecker postAuthenticationChecks = new DefaultPostAuthenticationChecks();
|
||||||
|
|
||||||
//~ Methods ========================================================================================================
|
//~ Methods ========================================================================================================
|
||||||
|
|
||||||
|
@ -100,8 +103,7 @@ public abstract class AbstractUserDetailsAuthenticationProvider implements Authe
|
||||||
doAfterPropertiesSet();
|
doAfterPropertiesSet();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Authentication authenticate(Authentication authentication)
|
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
|
||||||
throws AuthenticationException {
|
|
||||||
Assert.isInstanceOf(UsernamePasswordAuthenticationToken.class, authentication,
|
Assert.isInstanceOf(UsernamePasswordAuthenticationToken.class, authentication,
|
||||||
messages.getMessage("AbstractUserDetailsAuthenticationProvider.onlySupports",
|
messages.getMessage("AbstractUserDetailsAuthenticationProvider.onlySupports",
|
||||||
"Only UsernamePasswordAuthenticationToken is supported"));
|
"Only UsernamePasswordAuthenticationToken is supported"));
|
||||||
|
@ -129,20 +131,7 @@ public abstract class AbstractUserDetailsAuthenticationProvider implements Authe
|
||||||
Assert.notNull(user, "retrieveUser returned null - a violation of the interface contract");
|
Assert.notNull(user, "retrieveUser returned null - a violation of the interface contract");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!user.isAccountNonLocked()) {
|
preAuthenticationChecks.check(user);
|
||||||
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"));
|
|
||||||
}
|
|
||||||
|
|
||||||
// This check must come here, as we don't want to tell users
|
// This check must come here, as we don't want to tell users
|
||||||
// about account status unless they presented the correct credentials
|
// about account status unless they presented the correct credentials
|
||||||
|
@ -160,10 +149,7 @@ public abstract class AbstractUserDetailsAuthenticationProvider implements Authe
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!user.isCredentialsNonExpired()) {
|
postAuthenticationChecks.check(user);
|
||||||
throw new CredentialsExpiredException(messages.getMessage(
|
|
||||||
"AbstractUserDetailsAuthenticationProvider.credentialsExpired", "User credentials have expired"));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!cacheWasUsed) {
|
if (!cacheWasUsed) {
|
||||||
this.userCache.putUserInCache(user);
|
this.userCache.putUserInCache(user);
|
||||||
|
@ -278,4 +264,50 @@ public abstract class AbstractUserDetailsAuthenticationProvider implements Authe
|
||||||
public boolean supports(Class authentication) {
|
public boolean supports(Class authentication) {
|
||||||
return (UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication));
|
return (UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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"));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,8 @@ import org.springframework.security.ui.logout.LogoutHandler;
|
||||||
import org.springframework.security.userdetails.UserDetails;
|
import org.springframework.security.userdetails.UserDetails;
|
||||||
import org.springframework.security.userdetails.UserDetailsService;
|
import org.springframework.security.userdetails.UserDetailsService;
|
||||||
import org.springframework.security.userdetails.UsernameNotFoundException;
|
import org.springframework.security.userdetails.UsernameNotFoundException;
|
||||||
import org.springframework.security.userdetails.decorator.StatusCheckingUserDetailsService;
|
import org.springframework.security.userdetails.UserDetailsChecker;
|
||||||
|
import org.springframework.security.userdetails.checker.AccountStatusUserDetailsChecker;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
import org.springframework.web.bind.ServletRequestUtils;
|
import org.springframework.web.bind.ServletRequestUtils;
|
||||||
|
@ -44,8 +45,8 @@ public abstract class AbstractRememberMeServices implements RememberMeServices,
|
||||||
|
|
||||||
protected MessageSourceAccessor messages = SpringSecurityMessageSource.getAccessor();
|
protected MessageSourceAccessor messages = SpringSecurityMessageSource.getAccessor();
|
||||||
|
|
||||||
|
|
||||||
private UserDetailsService userDetailsService;
|
private UserDetailsService userDetailsService;
|
||||||
|
private UserDetailsChecker userDetailsChecker = new AccountStatusUserDetailsChecker();
|
||||||
private AuthenticationDetailsSource authenticationDetailsSource = new AuthenticationDetailsSourceImpl();
|
private AuthenticationDetailsSource authenticationDetailsSource = new AuthenticationDetailsSourceImpl();
|
||||||
|
|
||||||
private String cookieName = SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY;
|
private String cookieName = SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY;
|
||||||
|
@ -83,6 +84,7 @@ public abstract class AbstractRememberMeServices implements RememberMeServices,
|
||||||
try {
|
try {
|
||||||
String[] cookieTokens = decodeCookie(rememberMeCookie);
|
String[] cookieTokens = decodeCookie(rememberMeCookie);
|
||||||
user = processAutoLoginCookie(cookieTokens, request, response);
|
user = processAutoLoginCookie(cookieTokens, request, response);
|
||||||
|
userDetailsChecker.check(user);
|
||||||
} catch (CookieTheftException cte) {
|
} catch (CookieTheftException cte) {
|
||||||
cancelCookie(request, response);
|
cancelCookie(request, response);
|
||||||
throw cte;
|
throw cte;
|
||||||
|
@ -319,7 +321,7 @@ public abstract class AbstractRememberMeServices implements RememberMeServices,
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setUserDetailsService(UserDetailsService userDetailsService) {
|
public void setUserDetailsService(UserDetailsService userDetailsService) {
|
||||||
this.userDetailsService = new StatusCheckingUserDetailsService(userDetailsService);
|
this.userDetailsService = userDetailsService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setKey(String key) {
|
public void setKey(String key) {
|
||||||
|
|
|
@ -35,8 +35,9 @@ import org.springframework.security.ui.FilterChainOrder;
|
||||||
import org.springframework.security.ui.AbstractProcessingFilter;
|
import org.springframework.security.ui.AbstractProcessingFilter;
|
||||||
import org.springframework.security.userdetails.UserDetails;
|
import org.springframework.security.userdetails.UserDetails;
|
||||||
import org.springframework.security.userdetails.UserDetailsService;
|
import org.springframework.security.userdetails.UserDetailsService;
|
||||||
import org.springframework.security.userdetails.decorator.StatusCheckingUserDetailsService;
|
|
||||||
import org.springframework.security.userdetails.UsernameNotFoundException;
|
import org.springframework.security.userdetails.UsernameNotFoundException;
|
||||||
|
import org.springframework.security.userdetails.UserDetailsChecker;
|
||||||
|
import org.springframework.security.userdetails.checker.AccountStatusUserDetailsChecker;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
@ -120,6 +121,7 @@ public class SwitchUserProcessingFilter extends SpringSecurityFilter implements
|
||||||
private String switchFailureUrl;
|
private String switchFailureUrl;
|
||||||
private SwitchUserAuthorityChanger switchUserAuthorityChanger;
|
private SwitchUserAuthorityChanger switchUserAuthorityChanger;
|
||||||
private UserDetailsService userDetailsService;
|
private UserDetailsService userDetailsService;
|
||||||
|
private UserDetailsChecker userDetailsChecker = new AccountStatusUserDetailsChecker();
|
||||||
private boolean useRelativeContext;
|
private boolean useRelativeContext;
|
||||||
|
|
||||||
//~ Methods ========================================================================================================
|
//~ Methods ========================================================================================================
|
||||||
|
@ -204,8 +206,8 @@ public class SwitchUserProcessingFilter extends SpringSecurityFilter implements
|
||||||
logger.debug("Attempt to switch to user [" + username + "]");
|
logger.debug("Attempt to switch to user [" + username + "]");
|
||||||
}
|
}
|
||||||
|
|
||||||
// load the user by name
|
UserDetails targetUser = userDetailsService.loadUserByUsername(username);
|
||||||
UserDetails targetUser = this.userDetailsService.loadUserByUsername(username);
|
userDetailsChecker.check(targetUser);
|
||||||
|
|
||||||
// ok, create the switch user token
|
// ok, create the switch user token
|
||||||
targetUserRequest = createSwitchUserToken(request, targetUser);
|
targetUserRequest = createSwitchUserToken(request, targetUser);
|
||||||
|
@ -426,7 +428,7 @@ public class SwitchUserProcessingFilter extends SpringSecurityFilter implements
|
||||||
* @param userDetailsService The authentication dao
|
* @param userDetailsService The authentication dao
|
||||||
*/
|
*/
|
||||||
public void setUserDetailsService(UserDetailsService userDetailsService) {
|
public void setUserDetailsService(UserDetailsService userDetailsService) {
|
||||||
this.userDetailsService = new StatusCheckingUserDetailsService(userDetailsService);
|
this.userDetailsService = userDetailsService;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
package org.springframework.security.userdetails;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Luke Taylor
|
||||||
|
* @version $Id$
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
public interface UserDetailsChecker {
|
||||||
|
void check(UserDetails toCheck);
|
||||||
|
}
|
|
@ -1,39 +1,23 @@
|
||||||
package org.springframework.security.userdetails.decorator;
|
package org.springframework.security.userdetails.checker;
|
||||||
|
|
||||||
import org.springframework.security.userdetails.UserDetailsService;
|
import org.springframework.security.userdetails.UserDetailsChecker;
|
||||||
import org.springframework.security.userdetails.UserDetails;
|
import org.springframework.security.userdetails.UserDetails;
|
||||||
import org.springframework.security.LockedException;
|
import org.springframework.security.LockedException;
|
||||||
import org.springframework.security.DisabledException;
|
import org.springframework.security.DisabledException;
|
||||||
import org.springframework.security.AccountExpiredException;
|
import org.springframework.security.AccountExpiredException;
|
||||||
import org.springframework.security.CredentialsExpiredException;
|
import org.springframework.security.CredentialsExpiredException;
|
||||||
import org.springframework.security.SpringSecurityMessageSource;
|
import org.springframework.security.SpringSecurityMessageSource;
|
||||||
import org.springframework.security.AuthenticationException;
|
|
||||||
import org.springframework.dao.DataAccessException;
|
|
||||||
import org.springframework.context.support.MessageSourceAccessor;
|
import org.springframework.context.support.MessageSourceAccessor;
|
||||||
import org.springframework.util.Assert;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decorates a {@link UserDetailsService}, making it throw an exception if the account is locked, disabled etc. This
|
|
||||||
* removes the need for separate account status checks in classes which make use of a <tt>UserDetailsService</tt>.
|
|
||||||
*
|
|
||||||
* @author Luke Taylor
|
* @author Luke Taylor
|
||||||
* @version $Id$
|
* @version $Id$
|
||||||
*/
|
*/
|
||||||
public class StatusCheckingUserDetailsService implements UserDetailsService {
|
public class AccountStatusUserDetailsChecker implements UserDetailsChecker {
|
||||||
private UserDetailsService delegate;
|
|
||||||
|
|
||||||
protected MessageSourceAccessor messages = SpringSecurityMessageSource.getAccessor();
|
protected MessageSourceAccessor messages = SpringSecurityMessageSource.getAccessor();
|
||||||
|
|
||||||
public StatusCheckingUserDetailsService(UserDetailsService userDetailsService) {
|
public void check(UserDetails user) {
|
||||||
this.delegate = userDetailsService;
|
|
||||||
}
|
|
||||||
|
|
||||||
public UserDetails loadUserByUsername(String username) throws AuthenticationException, DataAccessException {
|
|
||||||
|
|
||||||
UserDetails user = delegate.loadUserByUsername(username);
|
|
||||||
|
|
||||||
Assert.notNull(user, "UserDetailsService returned null user, an interface violation.");
|
|
||||||
|
|
||||||
if (!user.isAccountNonLocked()) {
|
if (!user.isAccountNonLocked()) {
|
||||||
throw new LockedException(messages.getMessage("UserDetailsService.locked", "User account is locked"));
|
throw new LockedException(messages.getMessage("UserDetailsService.locked", "User account is locked"));
|
||||||
}
|
}
|
||||||
|
@ -51,7 +35,5 @@ public class StatusCheckingUserDetailsService implements UserDetailsService {
|
||||||
throw new CredentialsExpiredException(messages.getMessage("UserDetailsService.credentialsExpired",
|
throw new CredentialsExpiredException(messages.getMessage("UserDetailsService.credentialsExpired",
|
||||||
"User credentials have expired"));
|
"User credentials have expired"));
|
||||||
}
|
}
|
||||||
|
|
||||||
return user;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -50,14 +50,6 @@ import org.springframework.dao.DataRetrievalFailureException;
|
||||||
public class SiteminderAuthenticationProviderTests extends TestCase {
|
public class SiteminderAuthenticationProviderTests extends TestCase {
|
||||||
//~ Methods ========================================================================================================
|
//~ Methods ========================================================================================================
|
||||||
|
|
||||||
public static void main(String[] args) {
|
|
||||||
junit.textui.TestRunner.run(SiteminderAuthenticationProviderTests.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
public final void setUp() throws Exception {
|
|
||||||
super.setUp();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testAuthenticateFailsIfAccountExpired() {
|
public void testAuthenticateFailsIfAccountExpired() {
|
||||||
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("peter", "opal");
|
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("peter", "opal");
|
||||||
|
|
||||||
|
|
|
@ -478,11 +478,11 @@ public class AbstractProcessingFilterTests extends TestCase {
|
||||||
|
|
||||||
// Setup our test object, to grant access
|
// Setup our test object, to grant access
|
||||||
MockAbstractProcessingFilter filter = new MockAbstractProcessingFilter(true);
|
MockAbstractProcessingFilter filter = new MockAbstractProcessingFilter(true);
|
||||||
filter.setDefaultTargetUrl("http://monkeymachine.co.uk/");
|
filter.setDefaultTargetUrl("https://monkeymachine.co.uk/");
|
||||||
filter.setAlwaysUseDefaultTargetUrl(true);
|
filter.setAlwaysUseDefaultTargetUrl(true);
|
||||||
|
|
||||||
executeFilterInContainerSimulator(config, filter, request, response, chain);
|
executeFilterInContainerSimulator(config, filter, request, response, chain);
|
||||||
assertEquals("http://monkeymachine.co.uk/", response.getRedirectedUrl());
|
assertEquals("https://monkeymachine.co.uk/", response.getRedirectedUrl());
|
||||||
assertNotNull(SecurityContextHolder.getContext().getAuthentication());
|
assertNotNull(SecurityContextHolder.getContext().getAuthentication());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,43 +0,0 @@
|
||||||
package org.springframework.security.userdetails.decorator;
|
|
||||||
|
|
||||||
import org.springframework.security.userdetails.MockUserDetailsService;
|
|
||||||
import org.springframework.security.LockedException;
|
|
||||||
import org.springframework.security.DisabledException;
|
|
||||||
import org.springframework.security.CredentialsExpiredException;
|
|
||||||
import org.springframework.security.AccountExpiredException;
|
|
||||||
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Luke Taylor
|
|
||||||
* @version $Id$
|
|
||||||
*/
|
|
||||||
public class StatusCheckingUserDetailsServiceTests {
|
|
||||||
private StatusCheckingUserDetailsService us = new StatusCheckingUserDetailsService(new MockUserDetailsService());
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void validAccountIsSuccessfullyLoaded() throws Exception {
|
|
||||||
us.loadUserByUsername("valid");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = LockedException.class)
|
|
||||||
public void lockedAccountThrowsLockedException() throws Exception {
|
|
||||||
us.loadUserByUsername("locked");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = DisabledException.class)
|
|
||||||
public void disabledAccountThrowsDisabledException() throws Exception {
|
|
||||||
us.loadUserByUsername("disabled");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = CredentialsExpiredException.class)
|
|
||||||
public void credentialsExpiredAccountThrowsCredentialsExpiredException() throws Exception {
|
|
||||||
us.loadUserByUsername("credentialsExpired");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = AccountExpiredException.class)
|
|
||||||
public void expiredAccountThrowsAccountExpiredException() throws Exception {
|
|
||||||
us.loadUserByUsername("expired");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -34,9 +34,6 @@ import org.springframework.util.Assert;
|
||||||
* enabled/disabled status of the <code>UserDetails</code> because this is
|
* enabled/disabled status of the <code>UserDetails</code> because this is
|
||||||
* authentication-related and should have been enforced by another provider server.
|
* authentication-related and should have been enforced by another provider server.
|
||||||
* <p>
|
* <p>
|
||||||
* You can optionally have these checked by configuring wrapping the <tt>UserDetailsService</tt> in a
|
|
||||||
* {@link org.springframework.security.userdetails.decorator.StatusCheckingUserDetailsService} decorator.
|
|
||||||
* <p>
|
|
||||||
* The <code>UserDetails</code> returned by implementations is stored in the generated <code>AuthenticationToken</code>,
|
* The <code>UserDetails</code> returned by implementations is stored in the generated <code>AuthenticationToken</code>,
|
||||||
* so additional properties such as email addresses, telephone numbers etc can easily be stored.
|
* so additional properties such as email addresses, telephone numbers etc can easily be stored.
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in New Issue