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:
+ *
+ *
+ * - {@link SessionTrackingMode#COOKIE}
+ * - {@link SessionTrackingMode#SSL}
+ *
+ *
+ *
+ * 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()