Refactoring of ProviderManager to ensure that any AuthenticationException from the ConcurrentSessionController will prevent further polling of providers.

This commit is contained in:
Luke Taylor 2009-07-08 23:20:46 +00:00
parent d02bbbf560
commit 8a3930e673
2 changed files with 29 additions and 21 deletions

View File

@ -170,27 +170,34 @@ public class ProviderManager extends AbstractAuthenticationManager implements In
try { try {
result = provider.authenticate(authentication); result = provider.authenticate(authentication);
if (result != null) { if (result == null) {
copyDetails(authentication, result); continue;
sessionController.checkAuthenticationAllowed(result);
} }
} catch (AuthenticationException ae) { } catch (AccountStatusException e) {
lastException = ae; // SEC-546: Avoid polling additional providers if auth failure is due to invalid account status
result = null; lastException = e;
break;
} catch (AuthenticationException e) {
lastException = e;
continue;
} }
// SEC-546: Avoid polling additional providers if auth failure is due to invalid account status or assert result != null;
// disallowed concurrent login.
if (lastException instanceof AccountStatusException || lastException instanceof ConcurrentLoginException) { copyDetails(authentication, result);
try {
sessionController.checkAuthenticationAllowed(result);
} catch (AuthenticationException e) {
// SEC-546: Avoid polling additional providers if concurrent login check fails
lastException = e;
break; break;
} }
if (result != null) { sessionController.registerSuccessfulAuthentication(result);
sessionController.registerSuccessfulAuthentication(result); publishEvent(new AuthenticationSuccessEvent(result));
publishEvent(new AuthenticationSuccessEvent(result));
return result; return result;
}
} }
if (lastException == null) { if (lastException == null) {

View File

@ -16,7 +16,7 @@
package org.springframework.security.authentication; package org.springframework.security.authentication;
import static org.junit.Assert.*; import static org.junit.Assert.*;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.*;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
@ -45,8 +45,6 @@ import org.springframework.security.core.authority.AuthorityUtils;
*/ */
public class ProviderManagerTests { public class ProviderManagerTests {
//~ Methods ========================================================================================================
@Test(expected=ProviderNotFoundException.class) @Test(expected=ProviderNotFoundException.class)
public void authenticationFailsWithUnsupportedToken() throws Exception { public void authenticationFailsWithUnsupportedToken() throws Exception {
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Test", "Password", UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Test", "Password",
@ -185,11 +183,14 @@ public class ProviderManagerTests {
@Test(expected=ConcurrentLoginException.class) @Test(expected=ConcurrentLoginException.class)
public void concurrentLoginExceptionPreventsCallsToSubsequentProviders() throws Exception { public void concurrentLoginExceptionPreventsCallsToSubsequentProviders() throws Exception {
ProviderManager authMgr = makeProviderManager(); ProviderManager authMgr = makeProviderManager();
// Two providers so if the second is polled it will throw an AccountStatusException
authMgr.setProviders(Arrays.asList(new MockProvider(), new MockProviderWhichThrowsAccountStatusException()) );
TestingAuthenticationToken request = createAuthenticationToken();
ConcurrentSessionController ctrlr = mock(ConcurrentSessionController.class);
doThrow(new ConcurrentLoginException("mocked")).when(ctrlr).checkAuthenticationAllowed(request);
authMgr.setSessionController(ctrlr);
authMgr.setProviders(Arrays.asList(new MockProviderWhichThrowsConcurrentLoginException(), authMgr.authenticate(request);
new MockProviderWhichThrowsAccountStatusException()) );
authMgr.authenticate(createAuthenticationToken());
} }
private TestingAuthenticationToken createAuthenticationToken() { private TestingAuthenticationToken createAuthenticationToken() {