diff --git a/adapters/jboss/src/main/java/org/acegisecurity/adapters/jboss/JbossIntegrationFilter.java b/adapters/jboss/src/main/java/org/acegisecurity/adapters/jboss/JbossIntegrationFilter.java index 167908e0e7..34c1d0bf7a 100644 --- a/adapters/jboss/src/main/java/org/acegisecurity/adapters/jboss/JbossIntegrationFilter.java +++ b/adapters/jboss/src/main/java/org/acegisecurity/adapters/jboss/JbossIntegrationFilter.java @@ -45,6 +45,15 @@ import javax.servlet.ServletRequest; public class JbossIntegrationFilter extends AbstractIntegrationFilter { //~ Methods ================================================================ + /** + * Not supported for this type of well-known location. + * + * @param request DOCUMENT ME! + * @param authentication DOCUMENT ME! + */ + public void commitToContainer(ServletRequest request, + Authentication authentication) {} + public Object extractFromContainer(ServletRequest request) { Subject subject = null; diff --git a/adapters/jboss/src/test/java/org/acegisecurity/adapters/jboss/JbossIntegrationFilterTests.java b/adapters/jboss/src/test/java/org/acegisecurity/adapters/jboss/JbossIntegrationFilterTests.java index daa9509b04..e3348b7f53 100644 --- a/adapters/jboss/src/test/java/org/acegisecurity/adapters/jboss/JbossIntegrationFilterTests.java +++ b/adapters/jboss/src/test/java/org/acegisecurity/adapters/jboss/JbossIntegrationFilterTests.java @@ -77,6 +77,9 @@ public class JbossIntegrationFilterTests extends TestCase { PrincipalAcegiUserToken castResult = (PrincipalAcegiUserToken) result; assertEquals(principal, result); + + filter.commitToContainer(new MockHttpServletRequest(principal, null), + principal); } public void testReturnsNullIfContextReturnsSomethingOtherThanASubject() { diff --git a/changelog.txt b/changelog.txt index c715c7a929..2a7769e50c 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,3 +1,9 @@ +Changes in version 0.x (2004-xx-xx) +----------------------------------- + +* Added samples/quick-start +* Fixed issue with caching of Authentication objects + Changes in version 0.5 (2004-04-29) ----------------------------------- diff --git a/core/src/main/java/org/acegisecurity/adapters/HttpRequestIntegrationFilter.java b/core/src/main/java/org/acegisecurity/adapters/HttpRequestIntegrationFilter.java index e9410843f3..bb2981563e 100644 --- a/core/src/main/java/org/acegisecurity/adapters/HttpRequestIntegrationFilter.java +++ b/core/src/main/java/org/acegisecurity/adapters/HttpRequestIntegrationFilter.java @@ -15,6 +15,7 @@ package net.sf.acegisecurity.adapters; +import net.sf.acegisecurity.Authentication; import net.sf.acegisecurity.ui.AbstractIntegrationFilter; import org.apache.commons.logging.Log; @@ -42,6 +43,15 @@ public class HttpRequestIntegrationFilter extends AbstractIntegrationFilter { //~ Methods ================================================================ + /** + * Not supported for this type of well-known location. + * + * @param request DOCUMENT ME! + * @param authentication DOCUMENT ME! + */ + public void commitToContainer(ServletRequest request, + Authentication authentication) {} + public Object extractFromContainer(ServletRequest request) { if (request instanceof HttpServletRequest) { return ((HttpServletRequest) request).getUserPrincipal(); diff --git a/core/src/main/java/org/acegisecurity/ui/AbstractIntegrationFilter.java b/core/src/main/java/org/acegisecurity/ui/AbstractIntegrationFilter.java index ddca1baad3..c428288d9e 100644 --- a/core/src/main/java/org/acegisecurity/ui/AbstractIntegrationFilter.java +++ b/core/src/main/java/org/acegisecurity/ui/AbstractIntegrationFilter.java @@ -70,6 +70,17 @@ public abstract class AbstractIntegrationFilter implements Filter { //~ Methods ================================================================ + /** + * Writes a new Authentication object to the container's + * well-known location, if supported the subclass. + * + * @param request which may be required by the implementing method to + * access the well-known location for the current principal + * @param authentication the new object to be written to the container + */ + public abstract void commitToContainer(ServletRequest request, + Authentication authentication); + public void destroy() {} public void doFilter(ServletRequest request, ServletResponse response, @@ -112,12 +123,18 @@ public abstract class AbstractIntegrationFilter implements Filter { if ((ContextHolder.getContext() != null) && ContextHolder.getContext() instanceof SecureContext) { if (logger.isDebugEnabled()) { - logger.debug("Removing Authentication from ContextHolder"); + logger.debug( + "Updating container with new Authentication object, and then removing Authentication from ContextHolder"); } - // Get context holder and remove authentication information + // Get context holder SecureContext secureContext = (SecureContext) ContextHolder .getContext(); + + // Update container with new Authentication object (may have been updated during method invocation) + this.commitToContainer(request, secureContext.getAuthentication()); + + // Remove authentication information from ContextHolder secureContext.setAuthentication(null); ContextHolder.setContext((Context) secureContext); } else { diff --git a/core/src/main/java/org/acegisecurity/ui/AutoIntegrationFilter.java b/core/src/main/java/org/acegisecurity/ui/AutoIntegrationFilter.java index e5cf18aa58..ae6d17975f 100644 --- a/core/src/main/java/org/acegisecurity/ui/AutoIntegrationFilter.java +++ b/core/src/main/java/org/acegisecurity/ui/AutoIntegrationFilter.java @@ -57,6 +57,23 @@ import javax.servlet.http.HttpServletRequest; public class AutoIntegrationFilter extends AbstractIntegrationFilter { //~ Methods ================================================================ + public void commitToContainer(ServletRequest request, + Authentication authentication) { + if (request instanceof HttpServletRequest) { + HttpServletRequest httpRequest = (HttpServletRequest) request; + + if (getHttpSessionIntegrationFilter().extractFromContainer(request) != null) { + getHttpSessionIntegrationFilter().commitToContainer(request, + authentication); + + return; + } + + // Do not try JbossIntegrationFilter, as commit is unsupported. + // Do not try HttpRequestIntegrationFilter, as commit is unsupported. + } + } + public Object extractFromContainer(ServletRequest request) { if (request instanceof HttpServletRequest) { HttpServletRequest httpRequest = (HttpServletRequest) request; 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 bf979efc4b..90b161c778 100644 --- a/core/src/main/java/org/acegisecurity/ui/webapp/HttpSessionIntegrationFilter.java +++ b/core/src/main/java/org/acegisecurity/ui/webapp/HttpSessionIntegrationFilter.java @@ -67,6 +67,18 @@ public class HttpSessionIntegrationFilter extends AbstractIntegrationFilter { //~ Methods ================================================================ + public void commitToContainer(ServletRequest request, + Authentication authentication) { + if (request instanceof HttpServletRequest) { + HttpSession httpSession = ((HttpServletRequest) request).getSession(); + + if (httpSession != null) { + httpSession.setAttribute(ACEGI_SECURITY_AUTHENTICATION_KEY, + authentication); + } + } + } + public Object extractFromContainer(ServletRequest request) { if (request instanceof HttpServletRequest) { HttpSession httpSession = ((HttpServletRequest) request).getSession(); diff --git a/core/src/test/java/org/acegisecurity/adapters/HttpRequestIntegrationFilterTests.java b/core/src/test/java/org/acegisecurity/adapters/HttpRequestIntegrationFilterTests.java index 9c522008b8..4528cee39e 100644 --- a/core/src/test/java/org/acegisecurity/adapters/HttpRequestIntegrationFilterTests.java +++ b/core/src/test/java/org/acegisecurity/adapters/HttpRequestIntegrationFilterTests.java @@ -63,6 +63,9 @@ public class HttpRequestIntegrationFilterTests extends TestCase { PrincipalAcegiUserToken castResult = (PrincipalAcegiUserToken) result; assertEquals(principal, result); + + filter.commitToContainer(new MockHttpServletRequest(principal, null), + principal); } public void testHandlesIfHttpRequestIsNullForSomeReason() { diff --git a/core/src/test/java/org/acegisecurity/ui/AbstractIntegrationFilterTests.java b/core/src/test/java/org/acegisecurity/ui/AbstractIntegrationFilterTests.java index 32451e33ed..1b2bd3a72d 100644 --- a/core/src/test/java/org/acegisecurity/ui/AbstractIntegrationFilterTests.java +++ b/core/src/test/java/org/acegisecurity/ui/AbstractIntegrationFilterTests.java @@ -202,6 +202,11 @@ public class AbstractIntegrationFilterTests extends TestCase { super(); } + public void commitToContainer(ServletRequest request, + Authentication authentication) { + this.extractFromContainerResult = authentication; + } + public Object extractFromContainer(ServletRequest request) { return this.extractFromContainerResult; } diff --git a/core/src/test/java/org/acegisecurity/ui/AutoIntegrationFilterTests.java b/core/src/test/java/org/acegisecurity/ui/AutoIntegrationFilterTests.java index a877cdaabf..3f59868a3f 100644 --- a/core/src/test/java/org/acegisecurity/ui/AutoIntegrationFilterTests.java +++ b/core/src/test/java/org/acegisecurity/ui/AutoIntegrationFilterTests.java @@ -17,6 +17,7 @@ package net.sf.acegisecurity.ui; import junit.framework.TestCase; +import net.sf.acegisecurity.Authentication; import net.sf.acegisecurity.GrantedAuthority; import net.sf.acegisecurity.GrantedAuthorityImpl; import net.sf.acegisecurity.MockHttpServletRequest; @@ -68,6 +69,30 @@ public class AutoIntegrationFilterTests extends TestCase { junit.textui.TestRunner.run(AutoIntegrationFilterTests.class); } + public void testCommitForHttpSession() { + // This is the object we want to commit + PrincipalAcegiUserToken principal = new PrincipalAcegiUserToken("key", + "someone", "password", + new GrantedAuthority[] {new GrantedAuthorityImpl("SOME_ROLE")}); + + // Setup the mock so AutoIntegrationFilter detects HttpSessionIntegrationFilter should be used + MockHttpSessionIntegrationFilter mockHttpSessionIntegrationFilter = new MockHttpSessionIntegrationFilter(new PrincipalAcegiUserToken( + "x", "x", "x", + new GrantedAuthority[] {new GrantedAuthorityImpl("x")})); + + // Setup the AutoIntegrationFilter to use our mock HttpSessionIntegrationFilter object + AutoIntegrationFilter filter = new MockAutoIntegrationFilterHttpSession(mockHttpSessionIntegrationFilter); + + // Test we can commit the new object (this will override the principal with "x" in its properties) + filter.commitToContainer(new MockHttpServletRequest("ignored"), + principal); + + // Test the object was indeed committed and overwrote the principal with "x" in its properties + assertEquals(principal, + mockHttpSessionIntegrationFilter.extractFromContainer( + new MockHttpServletRequest("ignored"))); + } + public void testDetectsAuthenticationObjectInHttpRequest() { AutoIntegrationFilter filter = new AutoIntegrationFilter(); PrincipalAcegiUserToken principal = new PrincipalAcegiUserToken("key", @@ -201,6 +226,11 @@ public class AutoIntegrationFilterTests extends TestCase { super(); } + public void commitToContainer(ServletRequest request, + Authentication authentication) { + this.toReturn = authentication; + } + public Object extractFromContainer(ServletRequest request) { return this.toReturn; } 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 53d7c6309b..825c40a1d7 100644 --- a/core/src/test/java/org/acegisecurity/ui/webapp/HttpSessionIntegrationFilterTests.java +++ b/core/src/test/java/org/acegisecurity/ui/webapp/HttpSessionIntegrationFilterTests.java @@ -51,6 +51,48 @@ public class HttpSessionIntegrationFilterTests extends TestCase { junit.textui.TestRunner.run(HttpSessionIntegrationFilterTests.class); } + public void testCommitFailSilentlyIfNullsProvided() { + HttpSessionIntegrationFilter filter = new HttpSessionIntegrationFilter(); + filter.commitToContainer(null, null); + assertTrue(true); + } + + public void testCommitOperation() { + // Build an Authentication object we want returned + PrincipalAcegiUserToken principal = new PrincipalAcegiUserToken("key", + "someone", "password", + new GrantedAuthority[] {new GrantedAuthorityImpl("SOME_ROLE")}); + + // Build a mock request + MockHttpSession session = new MockHttpSession(); + MockHttpServletRequest request = new MockHttpServletRequest(null, + session); + + // Try to commit + HttpSessionIntegrationFilter filter = new HttpSessionIntegrationFilter(); + filter.commitToContainer(request, principal); + + // Check it committed the object + Object result = session.getAttribute(HttpSessionIntegrationFilter.ACEGI_SECURITY_AUTHENTICATION_KEY); + assertEquals(principal, result); + } + + public void testCommitOperationGracefullyIgnoredIfSessionIsNull() { + PrincipalAcegiUserToken principal = new PrincipalAcegiUserToken("key", + "someone", "password", + new GrantedAuthority[] {new GrantedAuthorityImpl("SOME_ROLE")}); + + // Build a mock request + MockHttpSession session = null; + MockHttpServletRequest request = new MockHttpServletRequest(null, + session); + + HttpSessionIntegrationFilter filter = new HttpSessionIntegrationFilter(); + filter.commitToContainer(request, principal); + + assertTrue(true); + } + public void testCorrectOperation() { // Build a mock session containing the authenticated user PrincipalAcegiUserToken principal = new PrincipalAcegiUserToken("key",