Fixed issue with caching by making AbstractIntegrationFilter (and its subclasses) write the new Authentication object to the well-known location.

This commit is contained in:
Ben Alex 2004-04-30 05:16:08 +00:00
parent ebf4603028
commit eaa92cd80a
11 changed files with 156 additions and 2 deletions

View File

@ -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;

View File

@ -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() {

View File

@ -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)
-----------------------------------

View File

@ -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();

View File

@ -70,6 +70,17 @@ public abstract class AbstractIntegrationFilter implements Filter {
//~ Methods ================================================================
/**
* Writes a new <code>Authentication</code> 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 {

View File

@ -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;

View File

@ -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();

View File

@ -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() {

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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",