From ac053dbda7776f08d8abec029461b96577a1cb67 Mon Sep 17 00:00:00 2001 From: Rob Winch Date: Fri, 19 Jul 2013 17:07:18 -0500 Subject: [PATCH] SEC-2156: AbstractSecurityWebApplicationInitializer configures SessionTrackingMode It also allows customization by overriding a method. --- ...ractSecurityWebApplicationInitializer.java | 33 +++++++++++++++++++ ...urityWebApplicationInitializerTests.groovy | 28 ++++++++++++++++ 2 files changed, 61 insertions(+) diff --git a/web/src/main/java/org/springframework/security/web/context/AbstractSecurityWebApplicationInitializer.java b/web/src/main/java/org/springframework/security/web/context/AbstractSecurityWebApplicationInitializer.java index f668b5932b..2845e817a9 100644 --- a/web/src/main/java/org/springframework/security/web/context/AbstractSecurityWebApplicationInitializer.java +++ b/web/src/main/java/org/springframework/security/web/context/AbstractSecurityWebApplicationInitializer.java @@ -17,12 +17,15 @@ package org.springframework.security.web.context; import java.util.Arrays; import java.util.EnumSet; +import java.util.HashSet; +import java.util.Set; import javax.servlet.DispatcherType; import javax.servlet.Filter; import javax.servlet.FilterRegistration.Dynamic; import javax.servlet.ServletContext; import javax.servlet.ServletException; +import javax.servlet.SessionTrackingMode; import org.springframework.context.ApplicationContext; import org.springframework.core.Conventions; @@ -83,6 +86,7 @@ public abstract class AbstractSecurityWebApplicationInitializer implements WebAp if(enableHttpSessionEventPublisher()) { servletContext.addListener("org.springframework.security.web.session.HttpSessionEventPublisher"); } + servletContext.setSessionTrackingModes(getSessionTrackingModes()); insertSpringSecurityFilterChain(servletContext); afterSpringSecurityFilterChain(servletContext); } @@ -207,6 +211,35 @@ public abstract class AbstractSecurityWebApplicationInitializer implements WebAp return SERVLET_CONTEXT_PREFIX + dispatcherServletName; } + /** + * Determines how a session should be tracked. By default, the following + * modes are used: + * + * + * + *

+ * Note that {@link SessionTrackingMode#URL} is intentionally omitted to + * help protected against session fixation + * attacks. + *

+ * + *

+ * Subclasses can override this method to make customizations. + *

+ * + * @return + */ + protected Set getSessionTrackingModes() { + Set modes = new HashSet(); + modes.add(SessionTrackingMode.COOKIE); + modes.add(SessionTrackingMode.SSL); + return modes; + } + /** * Return the to use the DispatcherServlet's * {@link WebApplicationContext} to find the {@link DelegatingFilterProxy} diff --git a/web/src/test/groovy/org/springframework/security/web/context/AbstractSecurityWebApplicationInitializerTests.groovy b/web/src/test/groovy/org/springframework/security/web/context/AbstractSecurityWebApplicationInitializerTests.groovy index d5ca378261..70a26df758 100644 --- a/web/src/test/groovy/org/springframework/security/web/context/AbstractSecurityWebApplicationInitializerTests.groovy +++ b/web/src/test/groovy/org/springframework/security/web/context/AbstractSecurityWebApplicationInitializerTests.groovy @@ -21,6 +21,7 @@ import javax.servlet.DispatcherType; import javax.servlet.Filter; import javax.servlet.FilterRegistration; import javax.servlet.ServletContext; +import javax.servlet.SessionTrackingMode; import org.springframework.security.web.session.HttpSessionEventPublisher; import org.springframework.web.filter.DelegatingFilterProxy; @@ -239,6 +240,33 @@ class AbstractSecurityWebApplicationInitializerTests extends Specification { success.message == "filters cannot be null or empty" } + def "sessionTrackingModes defaults"() { + setup: + ServletContext context = Mock() + FilterRegistration.Dynamic registration = Mock() + when: + new AbstractSecurityWebApplicationInitializer(){ }.onStartup(context) + then: + 1 * context.addFilter("springSecurityFilterChain", {DelegatingFilterProxy f -> f.targetBeanName == "springSecurityFilterChain" && f.contextAttribute == null}) >> registration + 1 * context.setSessionTrackingModes({Set modes -> modes.size() == 2 && modes.containsAll([SessionTrackingMode.COOKIE, SessionTrackingMode.SSL]) }) + } + + def "sessionTrackingModes override"() { + setup: + ServletContext context = Mock() + FilterRegistration.Dynamic registration = Mock() + when: + new AbstractSecurityWebApplicationInitializer(){ + @Override + public Set getSessionTrackingModes() { + return [SessionTrackingMode.COOKIE] + } + }.onStartup(context) + then: + 1 * context.addFilter("springSecurityFilterChain", {DelegatingFilterProxy f -> f.targetBeanName == "springSecurityFilterChain" && f.contextAttribute == null}) >> registration + 1 * context.setSessionTrackingModes({Set modes -> modes.size() == 1 && modes.containsAll([SessionTrackingMode.COOKIE]) }) + } + def "appendFilters filters with null"() { setup: Filter filter1 = Mock()