diff --git a/core/src/main/java/org/springframework/security/context/HttpSessionContextIntegrationFilter.java b/core/src/main/java/org/springframework/security/context/HttpSessionContextIntegrationFilter.java
index 79021e0912..2d69c748ec 100644
--- a/core/src/main/java/org/springframework/security/context/HttpSessionContextIntegrationFilter.java
+++ b/core/src/main/java/org/springframework/security/context/HttpSessionContextIntegrationFilter.java
@@ -95,20 +95,22 @@ import org.springframework.security.ui.FilterChainOrder;
* @author Luke Taylor
* @author Martin Algesten
*
+ * @deprecated Use SecurityContextPersistenceFilter instead.
+ *
* @version $Id$
*/
-public class HttpSessionContextIntegrationFilter extends SpringSecurityFilter implements InitializingBean {
+public class HttpSessionContextIntegrationFilter extends SecurityContextPersistenceFilter implements InitializingBean {
//~ Static fields/initializers =====================================================================================
- static final String FILTER_APPLIED = "__spring_security_session_integration_filter_applied";
-
+// static final String FILTER_APPLIED = "__spring_security_session_integration_filter_applied";
+//
public static final String SPRING_SECURITY_CONTEXT_KEY = "SPRING_SECURITY_CONTEXT";
//~ Instance fields ================================================================================================
private Class extends SecurityContext> contextClass = SecurityContextImpl.class;
- private Object contextObject;
+// private Object contextObject;
/**
* Indicates if this filter can create a HttpSession if
@@ -153,7 +155,14 @@ public class HttpSessionContextIntegrationFilter extends SpringSecurityFilter im
*/
private boolean cloneFromHttpSession = false;
- private AuthenticationTrustResolver authenticationTrustResolver = new AuthenticationTrustResolverImpl();
+ // private AuthenticationTrustResolver authenticationTrustResolver = new AuthenticationTrustResolverImpl();
+
+ private HttpSessionSecurityContextRepository repo = new HttpSessionSecurityContextRepository();
+
+ public HttpSessionContextIntegrationFilter() throws ServletException {
+// this.contextObject = generateNewContext();
+ super.setSecurityContextRepository(repo);
+ }
public boolean isCloneFromHttpSession() {
return cloneFromHttpSession;
@@ -161,374 +170,49 @@ public class HttpSessionContextIntegrationFilter extends SpringSecurityFilter im
public void setCloneFromHttpSession(boolean cloneFromHttpSession) {
this.cloneFromHttpSession = cloneFromHttpSession;
+ repo.setCloneFromHttpSession(cloneFromHttpSession);
}
- public HttpSessionContextIntegrationFilter() throws ServletException {
- this.contextObject = generateNewContext();
+ public boolean isAllowSessionCreation() {
+ return allowSessionCreation;
+ }
+
+ public void setAllowSessionCreation(boolean allowSessionCreation) {
+ this.allowSessionCreation = allowSessionCreation;
+ repo.setAllowSessionCreation(allowSessionCreation);
+ }
+
+ protected Class extends SecurityContext> getContextClass() {
+ return contextClass;
+ }
+
+ @SuppressWarnings("unchecked")
+ public void setContextClass(Class secureContext) {
+ this.contextClass = secureContext;
+ repo.setSecurityContextClass(secureContext);
+ }
+
+ public boolean isForceEagerSessionCreation() {
+ return forceEagerSessionCreation;
+ }
+
+ public void setForceEagerSessionCreation(boolean forceEagerSessionCreation) {
+ this.forceEagerSessionCreation = forceEagerSessionCreation;
+ super.setForceEagerSessionCreation(forceEagerSessionCreation);
+ }
+
+ public int getOrder() {
+ return FilterChainOrder.HTTP_SESSION_CONTEXT_FILTER;
}
//~ Methods ========================================================================================================
public void afterPropertiesSet() throws Exception {
- if ((this.contextClass == null) || (!SecurityContext.class.isAssignableFrom(this.contextClass))) {
- throw new IllegalArgumentException("context must be defined and implement SecurityContext "
- + "(typically use org.springframework.security.context.SecurityContextImpl; existing class is "
- + this.contextClass + ")");
- }
-
if (forceEagerSessionCreation && !allowSessionCreation) {
throw new IllegalArgumentException(
"If using forceEagerSessionCreation, you must set allowSessionCreation to also be true");
}
-
- contextObject = generateNewContext();
}
- public void doFilterHttp(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
- throws IOException, ServletException {
-
- if (request.getAttribute(FILTER_APPLIED) != null) {
- // ensure that filter is only applied once per request
- chain.doFilter(request, response);
-
- return;
- }
-
- HttpSession httpSession = safeGetSession(request, forceEagerSessionCreation);
- boolean httpSessionExistedAtStartOfRequest = httpSession != null;
- SecurityContext contextBeforeChainExecution = readSecurityContextFromSession(httpSession);
-
- // Make the HttpSession null, as we don't want to keep a reference to it lying
- // around in case chain.doFilter() invalidates it.
- httpSession = null;
-
- if (contextBeforeChainExecution == null) {
- contextBeforeChainExecution = generateNewContext();
-
- if (logger.isDebugEnabled()) {
- logger.debug("New SecurityContext instance will be associated with SecurityContextHolder");
- }
- } else {
- if (logger.isDebugEnabled()) {
- logger.debug("Obtained a valid SecurityContext from SPRING_SECURITY_CONTEXT to "
- + "associate with SecurityContextHolder: '" + contextBeforeChainExecution + "'");
- }
- }
-
- int contextHashBeforeChainExecution = contextBeforeChainExecution.hashCode();
- request.setAttribute(FILTER_APPLIED, Boolean.TRUE);
-
- // Create a wrapper that will eagerly update the session with the security context
- // if anything in the chain does a sendError() or sendRedirect().
- // See SEC-398
-
- OnRedirectUpdateSessionResponseWrapper responseWrapper =
- new OnRedirectUpdateSessionResponseWrapper( response, request,
- httpSessionExistedAtStartOfRequest, contextHashBeforeChainExecution );
-
- // Proceed with chain
-
- try {
- // This is the only place in this class where SecurityContextHolder.setContext() is called
- SecurityContextHolder.setContext(contextBeforeChainExecution);
-
- chain.doFilter(request, responseWrapper);
- }
- finally {
- // This is the only place in this class where SecurityContextHolder.getContext() is called
- SecurityContext contextAfterChainExecution = SecurityContextHolder.getContext();
-
- // Crucial removal of SecurityContextHolder contents - do this before anything else.
- SecurityContextHolder.clearContext();
-
- request.removeAttribute(FILTER_APPLIED);
-
- // storeSecurityContextInSession() might already be called by the response wrapper
- // if something in the chain called sendError() or sendRedirect(). This ensures we only call it
- // once per request.
- if ( !responseWrapper.isSessionUpdateDone() ) {
- storeSecurityContextInSession(contextAfterChainExecution, request,
- httpSessionExistedAtStartOfRequest, contextHashBeforeChainExecution);
- }
-
- if (logger.isDebugEnabled()) {
- logger.debug("SecurityContextHolder now cleared, as request processing completed");
- }
- }
- }
-
- /**
- * Gets the security context from the session (if available) and returns it.
- *
HttpSession with
- * the SecurityContext when a sendError() or sendRedirect
- * happens. See SEC-398. The class contains the fields needed to call
- * storeSecurityContextInSession()
- */
- private class OnRedirectUpdateSessionResponseWrapper extends HttpServletResponseWrapper {
-
- HttpServletRequest request;
- boolean httpSessionExistedAtStartOfRequest;
- int contextHashBeforeChainExecution;
-
- // Used to ensure storeSecurityContextInSession() is only
- // called once.
- boolean sessionUpdateDone = false;
-
- /**
- * Takes the parameters required to call storeSecurityContextInSession() in
- * addition to the response object we are wrapping.
- * @see HttpSessionContextIntegrationFilter#storeSecurityContextInSession(SecurityContext, HttpServletRequest, boolean, int)
- */
- public OnRedirectUpdateSessionResponseWrapper(HttpServletResponse response,
- HttpServletRequest request,
- boolean httpSessionExistedAtStartOfRequest,
- int contextHashBeforeChainExecution) {
- super(response);
- this.request = request;
- this.httpSessionExistedAtStartOfRequest = httpSessionExistedAtStartOfRequest;
- this.contextHashBeforeChainExecution = contextHashBeforeChainExecution;
- }
-
- /**
- * Makes sure the session is updated before calling the
- * superclass sendError()
- */
- public void sendError(int sc) throws IOException {
- doSessionUpdate();
- super.sendError(sc);
- }
-
- /**
- * Makes sure the session is updated before calling the
- * superclass sendError()
- */
- public void sendError(int sc, String msg) throws IOException {
- doSessionUpdate();
- super.sendError(sc, msg);
- }
-
- /**
- * Makes sure the session is updated before calling the
- * superclass sendRedirect()
- */
- public void sendRedirect(String location) throws IOException {
- doSessionUpdate();
- super.sendRedirect(location);
- }
-
- /**
- * Calls storeSecurityContextInSession()
- */
- private void doSessionUpdate() {
- if (sessionUpdateDone) {
- return;
- }
- SecurityContext securityContext = SecurityContextHolder.getContext();
- storeSecurityContextInSession(securityContext, request,
- httpSessionExistedAtStartOfRequest, contextHashBeforeChainExecution);
- sessionUpdateDone = true;
- }
-
- /**
- * Tells if the response wrapper has called
- * storeSecurityContextInSession().
- */
- public boolean isSessionUpdateDone() {
- return sessionUpdateDone;
- }
-
- }
}
diff --git a/core/src/main/java/org/springframework/security/context/SecurityContextPersistenceFilter.java b/core/src/main/java/org/springframework/security/context/SecurityContextPersistenceFilter.java
index da20fbef6e..01de284a62 100644
--- a/core/src/main/java/org/springframework/security/context/SecurityContextPersistenceFilter.java
+++ b/core/src/main/java/org/springframework/security/context/SecurityContextPersistenceFilter.java
@@ -73,6 +73,7 @@ public class SecurityContextPersistenceFilter extends SpringSecurityFilter {
// Crucial removal of SecurityContextHolder contents - do this before anything else.
SecurityContextHolder.clearContext();
repo.saveContext(contextAfterChainExecution, holder.getRequest(), holder.getResponse());
+ request.removeAttribute(FILTER_APPLIED);
if (logger.isDebugEnabled()) {
logger.debug("SecurityContextHolder now cleared, as request processing completed");
diff --git a/core/src/test/java/org/springframework/security/context/SecurityContextPersistenceFilterTests.java b/core/src/test/java/org/springframework/security/context/SecurityContextPersistenceFilterTests.java
index 9931905b5e..c842e40e35 100644
--- a/core/src/test/java/org/springframework/security/context/SecurityContextPersistenceFilterTests.java
+++ b/core/src/test/java/org/springframework/security/context/SecurityContextPersistenceFilterTests.java
@@ -98,23 +98,18 @@ public class SecurityContextPersistenceFilterTests {
}
@Test
- public void filterIsOnlyAppliedOncePerRequest() throws Exception {
+ public void filterIsNotAppliedAgainIfFilterAppliedAttributeIsSet() throws Exception {
final FilterChain chain = jmock.mock(FilterChain.class);
final MockHttpServletRequest request = new MockHttpServletRequest();
final MockHttpServletResponse response = new MockHttpServletResponse();
SecurityContextPersistenceFilter filter = new SecurityContextPersistenceFilter();
- final SecurityContextRepository repo = jmock.mock(SecurityContextRepository.class);
- filter.setSecurityContextRepository(repo);
- final SecurityContext sc = SecurityContextHolder.getContext();
+ filter.setSecurityContextRepository(jmock.mock(SecurityContextRepository.class));
jmock.checking(new Expectations() {{
- oneOf(repo).loadContext(with(aNonNull(HttpRequestResponseHolder.class))); will(returnValue(sc));
- oneOf(repo).saveContext(sc, request, response);
- exactly(2).of(chain).doFilter(request, response);
+ oneOf(chain).doFilter(request, response);
}});
- filter.doFilter(request, response, chain);
- assertNotNull(request.getAttribute(SecurityContextPersistenceFilter.FILTER_APPLIED));
+ request.setAttribute(SecurityContextPersistenceFilter.FILTER_APPLIED, Boolean.TRUE);
filter.doFilter(request, response, chain);
jmock.assertIsSatisfied();
}