From 59bf8602d2ecb1f6ece14885400dc7be9db47df5 Mon Sep 17 00:00:00 2001 From: Ben Alex Date: Tue, 14 Nov 2006 00:43:00 +0000 Subject: [PATCH] SEC-356: Add cloneFromHttpSession property. --- .../HttpSessionContextIntegrationFilter.java | 50 ++++++++++++++++--- 1 file changed, 43 insertions(+), 7 deletions(-) diff --git a/core/src/main/java/org/acegisecurity/context/HttpSessionContextIntegrationFilter.java b/core/src/main/java/org/acegisecurity/context/HttpSessionContextIntegrationFilter.java index aa4ac642e5..35c2dae4b7 100644 --- a/core/src/main/java/org/acegisecurity/context/HttpSessionContextIntegrationFilter.java +++ b/core/src/main/java/org/acegisecurity/context/HttpSessionContextIntegrationFilter.java @@ -15,12 +15,8 @@ package org.acegisecurity.context; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.beans.factory.InitializingBean; - import java.io.IOException; +import java.lang.reflect.Method; import javax.servlet.Filter; import javax.servlet.FilterChain; @@ -31,6 +27,12 @@ import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.util.Assert; +import org.springframework.util.ReflectionUtils; + /** *

Populates the {@link SecurityContextHolder} with information obtained from the HttpSession.

@@ -99,8 +101,28 @@ public class HttpSessionContextIntegrationFilter implements InitializingBean, Fi * are conscious of the session creation overhead. */ private boolean forceEagerSessionCreation = false; + + /** + * Indicates whether the SecurityContext will be cloned from the HttpSession. The + * default is to simply reference (ie the default is false). The default may cause issues if + * concurrent threads need to have a different security identity from other threads being concurrently processed + * that share the same HttpSession. In most normal environments this does not represent an issue, + * as changes to the security identity in one thread is allowed to affect the security identitiy in other + * threads associated with the same HttpSession. For unusual cases where this is not permitted, + * change this value to true and ensure the {@link #context} is set to a SecurityContext + * that implements {@link Cloneable} and overrides the clone() method. + */ + private boolean cloneFromHttpSession = false; + + public boolean isCloneFromHttpSession() { + return cloneFromHttpSession; + } - public HttpSessionContextIntegrationFilter() throws ServletException { + public void setCloneFromHttpSession(boolean cloneFromHttpSession) { + this.cloneFromHttpSession = cloneFromHttpSession; + } + + public HttpSessionContextIntegrationFilter() throws ServletException { this.contextObject = generateNewContext(); } @@ -145,7 +167,21 @@ public class HttpSessionContextIntegrationFilter implements InitializingBean, Fi httpSessionExistedAtStartOfRequest = true; Object contextFromSessionObject = httpSession.getAttribute(ACEGI_SECURITY_CONTEXT_KEY); - + + // Clone if required (see SEC-356) + if (cloneFromHttpSession) { + Assert.isInstanceOf(Cloneable.class, contextFromSessionObject, "Context must implement Clonable and provide a Object.clone() method"); + try { + Method m = contextFromSessionObject.getClass().getMethod("clone", new Class[] {}); + if (!m.isAccessible()) { + m.setAccessible(true); + } + contextFromSessionObject = m.invoke(contextFromSessionObject, new Object[] {}); + } catch (Exception ex) { + ReflectionUtils.handleReflectionException(ex); + } + } + if (contextFromSessionObject != null) { if (contextFromSessionObject instanceof SecurityContext) { if (logger.isDebugEnabled()) {