From 4152df1225b4be3747619a8659cce084a43aca26 Mon Sep 17 00:00:00 2001 From: Ben Alex Date: Tue, 4 May 2004 07:27:57 +0000 Subject: [PATCH] Allow filter to update multiple HttpSession attributes (useful if servlets etc expect to find an Authentication object in a given HttpSession attribute, like Jakarta Slide). --- .../webapp/HttpSessionIntegrationFilter.java | 56 ++++++++++++++++ .../HttpSessionIntegrationFilterTests.java | 64 +++++++++++++++++++ 2 files changed, 120 insertions(+) diff --git a/core/src/main/java/org/acegisecurity/ui/webapp/HttpSessionIntegrationFilter.java b/core/src/main/java/org/acegisecurity/ui/webapp/HttpSessionIntegrationFilter.java index 90b161c778..5baeb02b30 100644 --- a/core/src/main/java/org/acegisecurity/ui/webapp/HttpSessionIntegrationFilter.java +++ b/core/src/main/java/org/acegisecurity/ui/webapp/HttpSessionIntegrationFilter.java @@ -18,6 +18,9 @@ package net.sf.acegisecurity.ui.webapp; import net.sf.acegisecurity.Authentication; import net.sf.acegisecurity.ui.AbstractIntegrationFilter; +import java.util.Iterator; +import java.util.List; + import javax.servlet.ServletRequest; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; @@ -53,6 +56,13 @@ import javax.servlet.http.HttpSession; * request. *

* + *

+ * The filter can also copy the Authentication object to any + * number of additional HttpSession attributes. To use this + * capability, provide Strings indicating the additional + * attribute name(s) to {@link #setAdditionalAttributes(List)}. + *

+ * *

* See {@link AbstractIntegrationFilter} for further information. *

@@ -65,8 +75,21 @@ public class HttpSessionIntegrationFilter extends AbstractIntegrationFilter { public static final String ACEGI_SECURITY_AUTHENTICATION_KEY = "ACEGI_SECURITY_AUTHENTICATION"; + //~ Instance fields ======================================================== + + private List additionalAttributes = null; + //~ Methods ================================================================ + public void setAdditionalAttributes(List additionalAttributes) { + validateList(additionalAttributes); + this.additionalAttributes = additionalAttributes; + } + + public List getAdditionalAttributes() { + return additionalAttributes; + } + public void commitToContainer(ServletRequest request, Authentication authentication) { if (request instanceof HttpServletRequest) { @@ -75,6 +98,7 @@ public class HttpSessionIntegrationFilter extends AbstractIntegrationFilter { if (httpSession != null) { httpSession.setAttribute(ACEGI_SECURITY_AUTHENTICATION_KEY, authentication); + updateOtherLocations(httpSession, authentication); } } } @@ -87,6 +111,9 @@ public class HttpSessionIntegrationFilter extends AbstractIntegrationFilter { Object authObject = httpSession.getAttribute(ACEGI_SECURITY_AUTHENTICATION_KEY); if (authObject instanceof Authentication) { + updateOtherLocations(httpSession, + (Authentication) authObject); + return authObject; } } @@ -94,4 +121,33 @@ public class HttpSessionIntegrationFilter extends AbstractIntegrationFilter { return null; } + + private void updateOtherLocations(HttpSession session, + Authentication authentication) { + if (additionalAttributes == null) { + return; + } + + Iterator iter = additionalAttributes.iterator(); + + while (iter.hasNext()) { + String attribute = (String) iter.next(); + session.setAttribute(attribute, authentication); + } + } + + private void validateList(List newAdditionalAttributes) { + if (newAdditionalAttributes != null) { + Iterator iter = newAdditionalAttributes.iterator(); + + while (iter.hasNext()) { + Object objectToTest = iter.next(); + + if (!(objectToTest instanceof String)) { + throw new IllegalArgumentException( + "List of additional attributes can only contains Strings!"); + } + } + } + } } diff --git a/core/src/test/java/org/acegisecurity/ui/webapp/HttpSessionIntegrationFilterTests.java b/core/src/test/java/org/acegisecurity/ui/webapp/HttpSessionIntegrationFilterTests.java index 825c40a1d7..c3b3a2ba91 100644 --- a/core/src/test/java/org/acegisecurity/ui/webapp/HttpSessionIntegrationFilterTests.java +++ b/core/src/test/java/org/acegisecurity/ui/webapp/HttpSessionIntegrationFilterTests.java @@ -23,6 +23,9 @@ import net.sf.acegisecurity.MockHttpServletRequest; import net.sf.acegisecurity.MockHttpSession; import net.sf.acegisecurity.adapters.PrincipalAcegiUserToken; +import java.util.List; +import java.util.Vector; + /** * Tests {@link HttpSessionIntegrationFilter}. @@ -115,6 +118,19 @@ public class HttpSessionIntegrationFilterTests extends TestCase { assertEquals(principal, result); } + public void testDetectsInvalidAdditionalAttributes() { + HttpSessionIntegrationFilter filter = new HttpSessionIntegrationFilter(); + List list = new Vector(); + list.add(new Integer(4)); + + try { + filter.setAdditionalAttributes(list); + fail("Should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + assertTrue(true); + } + } + public void testHandlesIfHttpRequestIsNullForSomeReason() { HttpSessionIntegrationFilter filter = new HttpSessionIntegrationFilter(); assertEquals(null, filter.extractFromContainer(null)); @@ -132,4 +148,52 @@ public class HttpSessionIntegrationFilterTests extends TestCase { filter.extractFromContainer( new MockHttpServletRequest(null, new MockHttpSession()))); } + + public void testSettingEmptyListForAdditionalAttributesIsAcceptable() { + HttpSessionIntegrationFilter filter = new HttpSessionIntegrationFilter(); + filter.setAdditionalAttributes(new Vector()); + assertTrue(filter.getAdditionalAttributes() != null); + } + + public void testSettingNullForAdditionalAttributesIsAcceptable() { + HttpSessionIntegrationFilter filter = new HttpSessionIntegrationFilter(); + filter.setAdditionalAttributes(null); + assertNull(filter.getAdditionalAttributes()); + } + + public void testUpdatesAdditionalAttributes() { + // Build a mock session containing the authenticated user + PrincipalAcegiUserToken principal = new PrincipalAcegiUserToken("key", + "someone", "password", + new GrantedAuthority[] {new GrantedAuthorityImpl("SOME_ROLE")}); + MockHttpSession session = new MockHttpSession(); + session.setAttribute(HttpSessionIntegrationFilter.ACEGI_SECURITY_AUTHENTICATION_KEY, + principal); + + // Check our attributes are not presently set + assertNull(session.getAttribute("SOME_EXTRA_ATTRIBUTE_1")); + assertNull(session.getAttribute("SOME_EXTRA_ATTRIBUTE_2")); + + // Generate filter + HttpSessionIntegrationFilter filter = new HttpSessionIntegrationFilter(); + List list = new Vector(); + list.add("SOME_EXTRA_ATTRIBUTE_1"); + list.add("SOME_EXTRA_ATTRIBUTE_2"); + filter.setAdditionalAttributes(list); + + // Confirm filter can extract required credentials from session + Object result = filter.extractFromContainer(new MockHttpServletRequest( + null, session)); + + if (!(result instanceof PrincipalAcegiUserToken)) { + fail("Should have returned PrincipalAcegiUserToken"); + } + + PrincipalAcegiUserToken castResult = (PrincipalAcegiUserToken) result; + assertEquals(principal, result); + + // Now double-check it updated our earlier set additionalAttributes + assertEquals(principal, session.getAttribute("SOME_EXTRA_ATTRIBUTE_1")); + assertEquals(principal, session.getAttribute("SOME_EXTRA_ATTRIBUTE_2")); + } }