1
0
mirror of synced 2026-08-05 17:57:15 +00:00

SEC-546: Added AccountStatusException as base class for dibled, locked etc. Modified ProviderManager to prevent it querying further providers if either this exception or a ConcurrentLoginException is thrown.

This commit is contained in:
Luke Taylor
2008-01-08 13:33:20 +00:00
parent 99b7510482
commit c5e6a4cdfd
7 changed files with 256 additions and 206 deletions
@@ -21,15 +21,17 @@ import org.springframework.security.AuthenticationServiceException;
import org.springframework.security.GrantedAuthority;
import org.springframework.security.GrantedAuthorityImpl;
import org.springframework.security.MockApplicationEventPublisher;
import org.springframework.security.AccountStatusException;
import org.springframework.security.concurrent.ConcurrentSessionControllerImpl;
import org.springframework.security.concurrent.NullConcurrentSessionController;
import junit.framework.TestCase;
import org.springframework.security.concurrent.ConcurrentLoginException;
import java.util.Arrays;
import java.util.List;
import java.util.Vector;
import org.junit.Test;
import static org.junit.Assert.*;
/**
* Tests {@link ProviderManager}.
@@ -37,18 +39,162 @@ import java.util.Vector;
* @author Ben Alex
* @version $Id$
*/
public class ProviderManagerTests extends TestCase {
//~ Constructors ===================================================================================================
public ProviderManagerTests() {
}
public ProviderManagerTests(String arg0) {
super(arg0);
}
public class ProviderManagerTests {
//~ Methods ========================================================================================================
@Test(expected=ProviderNotFoundException.class)
public void authenticationFailsWithUnsupportedToken() throws Exception {
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Test", "Password",
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")});
ProviderManager mgr = makeProviderManager();
mgr.setApplicationEventPublisher(new MockApplicationEventPublisher(true));
mgr.authenticate(token);
}
@Test
public void authenticationSucceedsWithSupportedTokenAndReturnsExpectedObject() throws Exception {
TestingAuthenticationToken token = new TestingAuthenticationToken("Test", "Password",
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")});
ProviderManager mgr = makeProviderManager();
mgr.setApplicationEventPublisher(new MockApplicationEventPublisher(true));
Authentication result = mgr.authenticate(token);
if (!(result instanceof TestingAuthenticationToken)) {
fail("Should have returned instance of TestingAuthenticationToken");
}
TestingAuthenticationToken castResult = (TestingAuthenticationToken) result;
assertEquals("Test", castResult.getPrincipal());
assertEquals("Password", castResult.getCredentials());
assertEquals("ROLE_ONE", castResult.getAuthorities()[0].getAuthority());
assertEquals("ROLE_TWO", castResult.getAuthorities()[1].getAuthority());
}
@Test
public void authenticationSuccessWhenFirstProviderReturnsNullButSecondAuthenticates() {
TestingAuthenticationToken token = new TestingAuthenticationToken("Test", "Password",
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")});
ProviderManager mgr = makeProviderManagerWithMockProviderWhichReturnsNullInList();
mgr.setApplicationEventPublisher(new MockApplicationEventPublisher(true));
Authentication result = mgr.authenticate(token);
if (!(result instanceof TestingAuthenticationToken)) {
fail("Should have returned instance of TestingAuthenticationToken");
}
TestingAuthenticationToken castResult = (TestingAuthenticationToken) result;
assertEquals("Test", castResult.getPrincipal());
assertEquals("Password", castResult.getCredentials());
assertEquals("ROLE_ONE", castResult.getAuthorities()[0].getAuthority());
assertEquals("ROLE_TWO", castResult.getAuthorities()[1].getAuthority());
}
@Test
public void concurrentSessionControllerConfiguration() throws Exception {
ProviderManager target = new ProviderManager();
//The NullConcurrentSessionController should be the default
assertNotNull(target.getSessionController());
assertTrue(target.getSessionController() instanceof NullConcurrentSessionController);
ConcurrentSessionControllerImpl impl = new ConcurrentSessionControllerImpl();
target.setSessionController(impl);
assertEquals(impl, target.getSessionController());
}
@Test(expected=IllegalArgumentException.class)
public void startupFailsIfProviderListDoesNotContainProviders() throws Exception {
List providers = new Vector();
providers.add("THIS_IS_NOT_A_PROVIDER");
ProviderManager mgr = new ProviderManager();
mgr.setProviders(providers);
}
@Test(expected=IllegalArgumentException.class)
public void startupFailsIfProviderListNotSet() throws Exception {
ProviderManager mgr = new ProviderManager();
mgr.afterPropertiesSet();
}
@Test(expected=IllegalArgumentException.class)
public void testStartupFailsIfProviderListNull() throws Exception {
ProviderManager mgr = new ProviderManager();
mgr.setProviders(null);
}
@Test
public void detailsAreNotSetOnAuthenticationTokenIfAlreadySetByProvider() throws Exception {
Object requestDetails = "(Request Details)";
final Object resultDetails = "(Result Details)";
ProviderManager authMgr = makeProviderManager();
AuthenticationProvider provider = new AuthenticationProvider() {
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
((TestingAuthenticationToken)authentication).setDetails(resultDetails);
return authentication;
}
public boolean supports(Class authentication) {
return true;
}
};
authMgr.setProviders(Arrays.asList(provider));
TestingAuthenticationToken request = createAuthenticationToken();
request.setDetails(requestDetails);
Authentication result = authMgr.authenticate(request);
assertEquals(resultDetails, result.getDetails());
}
@Test
public void detailsAreSetOnAuthenticationTokenIfNotAlreadySetByProvider() throws Exception {
Object details = new Object();
ProviderManager authMgr = makeProviderManager();
TestingAuthenticationToken request = createAuthenticationToken();
request.setDetails(details);
Authentication result = authMgr.authenticate(request);
assertEquals(details, result.getDetails());
}
// SEC-546
@Test(expected=AccountStatusException.class)
public void accountStatusExceptionPreventsCallsToSubsequentProviders() throws Exception {
ProviderManager authMgr = makeProviderManager();
authMgr.setProviders(Arrays.asList(new MockProviderWhichThrowsAccountStatusException(),
new MockProviderWhichThrowsConcurrentLoginException()) );
authMgr.authenticate(createAuthenticationToken());
}
@Test(expected=ConcurrentLoginException.class)
public void concurrentLoginExceptionPreventsCallsToSubsequentProviders() throws Exception {
ProviderManager authMgr = makeProviderManager();
authMgr.setProviders(Arrays.asList(new MockProviderWhichThrowsConcurrentLoginException(),
new MockProviderWhichThrowsAccountStatusException()) );
authMgr.authenticate(createAuthenticationToken());
}
private TestingAuthenticationToken createAuthenticationToken() {
return new TestingAuthenticationToken("name", "password", new GrantedAuthorityImpl[0]);
}
private ProviderManager makeProviderManager() throws Exception {
MockProvider provider1 = new MockProvider();
List providers = new Vector();
@@ -74,157 +220,7 @@ public class ProviderManagerTests extends TestCase {
return mgr;
}
public void testAuthenticationFails() throws Exception {
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Test", "Password",
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")});
ProviderManager mgr = makeProviderManager();
mgr.setApplicationEventPublisher(new MockApplicationEventPublisher(true));
try {
mgr.authenticate(token);
fail("Should have thrown ProviderNotFoundException");
} catch (ProviderNotFoundException expected) {
assertTrue(true);
}
}
public void testAuthenticationSuccess() throws Exception {
TestingAuthenticationToken token = new TestingAuthenticationToken("Test", "Password",
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")});
ProviderManager mgr = makeProviderManager();
mgr.setApplicationEventPublisher(new MockApplicationEventPublisher(true));
Authentication result = mgr.authenticate(token);
if (!(result instanceof TestingAuthenticationToken)) {
fail("Should have returned instance of TestingAuthenticationToken");
}
TestingAuthenticationToken castResult = (TestingAuthenticationToken) result;
assertEquals("Test", castResult.getPrincipal());
assertEquals("Password", castResult.getCredentials());
assertEquals("ROLE_ONE", castResult.getAuthorities()[0].getAuthority());
assertEquals("ROLE_TWO", castResult.getAuthorities()[1].getAuthority());
}
public void testAuthenticationSuccessWhenFirstProviderReturnsNullButSecondAuthenticates() {
TestingAuthenticationToken token = new TestingAuthenticationToken("Test", "Password",
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")});
ProviderManager mgr = makeProviderManagerWithMockProviderWhichReturnsNullInList();
mgr.setApplicationEventPublisher(new MockApplicationEventPublisher(true));
Authentication result = mgr.authenticate(token);
if (!(result instanceof TestingAuthenticationToken)) {
fail("Should have returned instance of TestingAuthenticationToken");
}
TestingAuthenticationToken castResult = (TestingAuthenticationToken) result;
assertEquals("Test", castResult.getPrincipal());
assertEquals("Password", castResult.getCredentials());
assertEquals("ROLE_ONE", castResult.getAuthorities()[0].getAuthority());
assertEquals("ROLE_TWO", castResult.getAuthorities()[1].getAuthority());
}
public void testConcurrentSessionControllerConfiguration() throws Exception {
ProviderManager target = new ProviderManager();
//The NullConcurrentSessionController should be the default
assertNotNull(target.getSessionController());
assertTrue(target.getSessionController() instanceof NullConcurrentSessionController);
ConcurrentSessionControllerImpl impl = new ConcurrentSessionControllerImpl();
target.setSessionController(impl);
assertEquals(impl, target.getSessionController());
}
public void testStartupFailsIfProviderListDoesNotContainingProviders() throws Exception {
List providers = new Vector();
providers.add("THIS_IS_NOT_A_PROVIDER");
ProviderManager mgr = new ProviderManager();
try {
mgr.setProviders(providers);
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
}
public void testStartupFailsIfProviderListNotSet() throws Exception {
ProviderManager mgr = new ProviderManager();
try {
mgr.afterPropertiesSet();
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
}
public void testStartupFailsIfProviderListNull() throws Exception {
ProviderManager mgr = new ProviderManager();
try {
mgr.setProviders(null);
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
}
public void testSuccessfulStartup() throws Exception {
ProviderManager mgr = makeProviderManager();
mgr.afterPropertiesSet();
assertTrue(true);
assertEquals(1, mgr.getProviders().size());
}
public void testDetailsAreNotSetOnAuthenticationTokenIfAlreadySetByProvider() throws Exception {
Object requestDetails = new String("(Request Details)");
final Object resultDetails = new String("(Result Details)");
ProviderManager authMgr = makeProviderManager();
AuthenticationProvider provider = new AuthenticationProvider() {
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
((TestingAuthenticationToken)authentication).setDetails(resultDetails);
return authentication;
}
public boolean supports(Class authentication) {
return true;
}
};
authMgr.setProviders(Arrays.asList(new AuthenticationProvider[] {provider}));
TestingAuthenticationToken request = createAuthenticationToken();
request.setDetails(requestDetails);
Authentication result = authMgr.authenticate(request);
assertEquals(resultDetails, result.getDetails());
}
public void testDetailsAreSetOnAuthenticationTokenIfNotAlreadySetByProvider() throws Exception {
Object details = new Object();
ProviderManager authMgr = makeProviderManager();
TestingAuthenticationToken request = createAuthenticationToken();
request.setDetails(details);
Authentication result = authMgr.authenticate(request);
assertEquals(details, result.getDetails());
}
private TestingAuthenticationToken createAuthenticationToken() {
return new TestingAuthenticationToken("name", "password", new GrantedAuthorityImpl[0]);
}
//~ Inner Classes ==================================================================================================
private class MockProvider implements AuthenticationProvider {
@@ -262,4 +258,25 @@ public class ProviderManagerTests extends TestCase {
}
}
}
private class MockProviderWhichThrowsAccountStatusException implements AuthenticationProvider {
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
throw new AccountStatusException("xxx") {};
}
public boolean supports(Class authentication) {
return true;
}
}
private class MockProviderWhichThrowsConcurrentLoginException implements AuthenticationProvider {
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
throw new ConcurrentLoginException("xxx") {};
}
public boolean supports(Class authentication) {
return true;
}
}
}