From 2cbe42f493367e0dd6fb082dc2234a27d1717600 Mon Sep 17 00:00:00 2001 From: Ben Alex Date: Thu, 3 Nov 2005 04:14:12 +0000 Subject: [PATCH] SEC-7: Allow better chaining of authentication providers. --- .../providers/ProviderManager.java | 32 +++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/org/acegisecurity/providers/ProviderManager.java b/core/src/main/java/org/acegisecurity/providers/ProviderManager.java index 6dcf70bd8d..3e21bc63b1 100644 --- a/core/src/main/java/org/acegisecurity/providers/ProviderManager.java +++ b/core/src/main/java/org/acegisecurity/providers/ProviderManager.java @@ -35,6 +35,22 @@ import java.util.List; * AuthenticationProvider}s. Can optionally be configured with a {@link * ConcurrentSessionController} to limit the number of sessions a user can * have. + * + *

+ * AuthenticationProviders are tried in order until one provides a + * non-null response. A non-null response indicates the provider had authority + * to decide on the authentication request and no further providers are tried. + * If an AuthenticationException is thrown by a provider, it is + * retained until subsequent providers are tried. If a subsequent provider + * successfully authenticates the request, the earlier authentication + * exception is disregarded and the successful authentication will be used. If + * no subsequent provider provides a non-null response, or a new + * AuthenticationException, the last + * AuthenticationException received will be used. If no provider + * returns a non-null response, or indicates it can even process an + * Authentication, the ProviderManager will throw a + * ProviderNotFoundException. + *

* * @author Ben Alex * @author Wesley Hall @@ -107,7 +123,7 @@ public class ProviderManager extends AbstractAuthenticationManager * {@link NullConcurrentSessionController} if a specific one has not been * set. * - * @return{@link ConcurrentSessionController} instance + * @return {@link ConcurrentSessionController} instance */ public ConcurrentSessionController getSessionController() { return sessionController; @@ -150,6 +166,8 @@ public class ProviderManager extends AbstractAuthenticationManager sessionController.checkAuthenticationAllowed(authentication); + AuthenticationException lastException = null; + while (iter.hasNext()) { AuthenticationProvider provider = (AuthenticationProvider) iter .next(); @@ -158,7 +176,13 @@ public class ProviderManager extends AbstractAuthenticationManager logger.debug("Authentication attempt using " + provider.getClass().getName()); - Authentication result = provider.authenticate(authentication); + Authentication result = null; + + try { + result = provider.authenticate(authentication); + } catch (AuthenticationException ae) { + lastException = ae; + } if (result != null) { sessionController.registerSuccessfulAuthentication(result); @@ -168,6 +192,10 @@ public class ProviderManager extends AbstractAuthenticationManager } } + if (lastException != null) { + throw lastException; + } + throw new ProviderNotFoundException("No authentication provider for " + toTest.getName()); }