Browse Source

Modify AbstractAuthenticationManager to transfer the details object from authentication request to the resulting authentication token, provided it has not already been set on the latter by an authentication provider.

Luke Taylor 19 years ago
parent
commit
5475ab0575

+ 26 - 4
core/src/main/java/org/acegisecurity/AbstractAuthenticationManager.java

@@ -15,6 +15,8 @@
 
 package org.acegisecurity;
 
+import org.acegisecurity.providers.AbstractAuthenticationToken;
+
 /**
  * An abstract implementation of the {@link AuthenticationManager}.
  *
@@ -37,22 +39,42 @@ public abstract class AbstractAuthenticationManager
      * object that failed.
      * </p>
      *
-     * @param authentication the authentication request object
+     * @param authRequest the authentication request object
      *
      * @return a fully authenticated object including credentials
      *
      * @throws AuthenticationException if authentication fails
      */
-    public final Authentication authenticate(Authentication authentication)
+    public final Authentication authenticate(Authentication authRequest)
         throws AuthenticationException {
         try {
-            return doAuthentication(authentication);
+            Authentication authResult = doAuthentication(authRequest);
+            copyDetails(authRequest, authResult);
+
+            return authResult;
         } catch (AuthenticationException e) {
-            e.setAuthentication(authentication);
+            e.setAuthentication(authRequest);
             throw e;
         }
     }
 
+    /**
+     * Copies the authentication details from a source Authentication object
+     * to a destination one, provided the latter does not already have one
+     * set.
+     *
+     * @param source source authentication
+     * @param dest the destination authentication object
+     */
+    private void copyDetails(Authentication source, Authentication dest) {
+        if((dest instanceof AbstractAuthenticationToken)
+              && dest.getDetails() == null) {
+           AbstractAuthenticationToken token = (AbstractAuthenticationToken)dest;
+
+           token.setDetails(source.getDetails());
+        }
+    }
+
     /**
      * <p>
      * Concrete implementations of this class override this method to provide

+ 82 - 0
core/src/test/java/org/acegisecurity/AbstractAuthenticationManagerTests.java

@@ -0,0 +1,82 @@
+/* Copyright 2004, 2005 Acegi Technology Pty Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.acegisecurity;
+
+import junit.framework.TestCase;
+import org.acegisecurity.providers.TestingAuthenticationToken;
+
+/**
+ * Tests {@link AbstractAuthenticationManager}.
+ *
+ * @author Luke Taylor
+ * @version $Id$
+ */
+public class AbstractAuthenticationManagerTests extends TestCase {
+    //~ Constructors ===========================================================
+
+    public AbstractAuthenticationManagerTests() {
+        super();
+    }
+
+    public AbstractAuthenticationManagerTests(String arg0) {
+        super(arg0);
+    }
+
+    //~ Methods ================================================================
+
+    public void testDetailsAreSetOnAuthenticationTokenIfNotAlreadySetByProvider() {
+        AuthenticationManager authMgr = createAuthenticationManager(null);
+        Object details = new Object();
+
+        TestingAuthenticationToken request = createAuthenticationToken();
+        request.setDetails(details);
+
+        Authentication result = authMgr.authenticate(request);
+        assertEquals(details, result.getDetails());
+    }
+
+    public void testDetailsAreNotSetOnAuthenticationTokenIfAlreadySetByProvider() {
+        Object requestDetails = new String("(Request Details)");
+        Object resultDetails = new String("(Result Details)");
+        AuthenticationManager authMgr = createAuthenticationManager(resultDetails);
+
+        TestingAuthenticationToken request = createAuthenticationToken();
+        request.setDetails(requestDetails);
+
+        Authentication result = authMgr.authenticate(request);
+        assertEquals(resultDetails, result.getDetails());
+    }
+
+    private TestingAuthenticationToken createAuthenticationToken() {
+        return new TestingAuthenticationToken("name","password", new GrantedAuthorityImpl[0]);
+    }
+
+    /**
+     * Creates an AuthenticationManager which will return a token with the given
+     * details object set on it.
+     */
+    private AuthenticationManager createAuthenticationManager(final Object resultDetails) {
+        return new AbstractAuthenticationManager() {
+            protected Authentication doAuthentication(Authentication authentication)
+                    throws AuthenticationException {
+                TestingAuthenticationToken token = createAuthenticationToken();
+                token.setDetails(resultDetails);
+
+                return token;
+            }
+        };
+    }
+}