|
|
|
@ -15,12 +15,8 @@ |
|
|
|
|
|
|
|
|
|
|
|
package org.acegisecurity.context; |
|
|
|
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.io.IOException; |
|
|
|
|
|
|
|
import java.lang.reflect.Method; |
|
|
|
|
|
|
|
|
|
|
|
import javax.servlet.Filter; |
|
|
|
import javax.servlet.Filter; |
|
|
|
import javax.servlet.FilterChain; |
|
|
|
import javax.servlet.FilterChain; |
|
|
|
@ -31,6 +27,12 @@ import javax.servlet.ServletResponse; |
|
|
|
import javax.servlet.http.HttpServletRequest; |
|
|
|
import javax.servlet.http.HttpServletRequest; |
|
|
|
import javax.servlet.http.HttpSession; |
|
|
|
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; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* <p>Populates the {@link SecurityContextHolder} with information obtained from the <code>HttpSession</code>.</p> |
|
|
|
* <p>Populates the {@link SecurityContextHolder} with information obtained from the <code>HttpSession</code>.</p> |
|
|
|
@ -99,8 +101,28 @@ public class HttpSessionContextIntegrationFilter implements InitializingBean, Fi |
|
|
|
* are conscious of the session creation overhead. |
|
|
|
* are conscious of the session creation overhead. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
private boolean forceEagerSessionCreation = false; |
|
|
|
private boolean forceEagerSessionCreation = false; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* Indicates whether the <code>SecurityContext</code> will be cloned from the <code>HttpSession</code>. The |
|
|
|
|
|
|
|
* default is to simply reference (ie the default is <code>false</code>). 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 <code>HttpSession</code>. 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 <code>HttpSession</code>. For unusual cases where this is not permitted, |
|
|
|
|
|
|
|
* change this value to <code>true</code> and ensure the {@link #context} is set to a <code>SecurityContext</code> |
|
|
|
|
|
|
|
* that implements {@link Cloneable} and overrides the <code>clone()</code> 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(); |
|
|
|
this.contextObject = generateNewContext(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@ -145,7 +167,21 @@ public class HttpSessionContextIntegrationFilter implements InitializingBean, Fi |
|
|
|
httpSessionExistedAtStartOfRequest = true; |
|
|
|
httpSessionExistedAtStartOfRequest = true; |
|
|
|
|
|
|
|
|
|
|
|
Object contextFromSessionObject = httpSession.getAttribute(ACEGI_SECURITY_CONTEXT_KEY); |
|
|
|
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 != null) { |
|
|
|
if (contextFromSessionObject instanceof SecurityContext) { |
|
|
|
if (contextFromSessionObject instanceof SecurityContext) { |
|
|
|
if (logger.isDebugEnabled()) { |
|
|
|
if (logger.isDebugEnabled()) { |
|
|
|
|