diff --git a/core/src/main/java/org/springframework/security/config/BeanIds.java b/core/src/main/java/org/springframework/security/config/BeanIds.java
index 6e7a79ee8f..651300627f 100644
--- a/core/src/main/java/org/springframework/security/config/BeanIds.java
+++ b/core/src/main/java/org/springframework/security/config/BeanIds.java
@@ -46,6 +46,7 @@ public abstract class BeanIds {
public static final String REMEMBER_ME_SERVICES = "_rememberMeServices";
public static final String DEFAULT_LOGIN_PAGE_GENERATING_FILTER = "_defaultLoginPageFilter";
public static final String SECURITY_CONTEXT_HOLDER_AWARE_REQUEST_FILTER = "_securityContextHolderAwareRequestFilter";
+ public static final String SESSION_FIXATION_PROTECTION_FILTER = "_sessionFixationProtectionFilter";
public static final String METHOD_SECURITY_INTERCEPTOR = "_methodSecurityInterceptor";
public static final String METHOD_DEFINITION_SOURCE_ADVISOR = "_methodDefinitionSourceAdvisor";
public static final String PROTECT_POINTCUT_POST_PROCESSOR = "_protectPointcutPostProcessor";
diff --git a/core/src/main/java/org/springframework/security/config/HttpSecurityBeanDefinitionParser.java b/core/src/main/java/org/springframework/security/config/HttpSecurityBeanDefinitionParser.java
index 260e2ee637..bfa42b5525 100644
--- a/core/src/main/java/org/springframework/security/config/HttpSecurityBeanDefinitionParser.java
+++ b/core/src/main/java/org/springframework/security/config/HttpSecurityBeanDefinitionParser.java
@@ -30,6 +30,7 @@ import org.springframework.security.securechannel.SecureChannelProcessor;
import org.springframework.security.securechannel.RetryWithHttpEntryPoint;
import org.springframework.security.securechannel.RetryWithHttpsEntryPoint;
import org.springframework.security.ui.ExceptionTranslationFilter;
+import org.springframework.security.ui.SessionFixationProtectionFilter;
import org.springframework.security.ui.webapp.DefaultLoginPageGeneratingFilter;
import org.springframework.security.util.FilterChainProxy;
import org.springframework.security.util.RegexUrlPathMatcher;
@@ -53,6 +54,11 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
static final String DEF_REALM = "Spring Security Application";
static final String ATT_PATH_PATTERN = "pattern";
+
+ static final String ATT_SESSION_FIXATION_PROTECTION = "session-fixation-protection";
+ static final String OPT_SESSION_FIXATION_NO_PROTECTION = "none";
+ static final String OPT_SESSION_FIXATION_CLEAN_SESSION = "newSession";
+ static final String OPT_SESSION_FIXATION_MIGRATE_SESSION = "migrateSession";
static final String ATT_PATH_TYPE = "path-type";
static final String DEF_PATH_TYPE_ANT = "ant";
@@ -109,6 +115,21 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
httpScif.getPropertyValues().addPropertyValue("allowSessionCreation", Boolean.TRUE);
httpScif.getPropertyValues().addPropertyValue("forceEagerSessionCreation", Boolean.FALSE);
}
+
+ String sessionFixationAttribute = element.getAttribute(ATT_SESSION_FIXATION_PROTECTION);
+
+ if(!StringUtils.hasText(sessionFixationAttribute)) {
+ sessionFixationAttribute = OPT_SESSION_FIXATION_MIGRATE_SESSION;
+ }
+
+ if (!sessionFixationAttribute.equals(OPT_SESSION_FIXATION_NO_PROTECTION)) {
+ BeanDefinitionBuilder sessionFixationFilter =
+ BeanDefinitionBuilder.rootBeanDefinition(SessionFixationProtectionFilter.class);
+ sessionFixationFilter.addPropertyValue("migrateSessionAttributes",
+ sessionFixationAttribute.equals(OPT_SESSION_FIXATION_MIGRATE_SESSION));
+ parserContext.getRegistry().registerBeanDefinition(BeanIds.SESSION_FIXATION_PROTECTION_FILTER,
+ sessionFixationFilter.getBeanDefinition());
+ }
BeanDefinitionBuilder filterSecurityInterceptorBuilder
= BeanDefinitionBuilder.rootBeanDefinition(FilterSecurityInterceptor.class);
@@ -127,6 +148,7 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
if (!StringUtils.hasText(provideServletApi)) {
provideServletApi = DEF_SERVLET_API_PROVISION;
}
+
if ("true".equals(provideServletApi)) {
parserContext.getRegistry().registerBeanDefinition(BeanIds.SECURITY_CONTEXT_HOLDER_AWARE_REQUEST_FILTER,
new RootBeanDefinition(SecurityContextHolderAwareRequestFilter.class));
@@ -134,7 +156,7 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
filterChainProxy.getPropertyValues().addPropertyValue("filterChainMap", filterChainMap);
- // Set up the access manager and authentication mananger references for http
+ // Set up the access manager and authentication manager references for http
String accessManagerId = element.getAttribute(ATT_ACCESS_MGR);
if (!StringUtils.hasText(accessManagerId)) {
diff --git a/core/src/test/java/org/springframework/security/config/HttpSecurityBeanDefinitionParserTests.java b/core/src/test/java/org/springframework/security/config/HttpSecurityBeanDefinitionParserTests.java
index 5e994afff6..d17cc635bb 100644
--- a/core/src/test/java/org/springframework/security/config/HttpSecurityBeanDefinitionParserTests.java
+++ b/core/src/test/java/org/springframework/security/config/HttpSecurityBeanDefinitionParserTests.java
@@ -6,6 +6,7 @@ import org.springframework.security.intercept.web.FilterInvocationDefinitionSour
import org.springframework.security.intercept.web.FilterInvocation;
import org.springframework.security.securechannel.ChannelProcessingFilter;
import org.springframework.security.ui.ExceptionTranslationFilter;
+import org.springframework.security.ui.SessionFixationProtectionFilter;
import org.springframework.security.ui.preauth.x509.X509PreAuthenticatedProcessingFilter;
import org.springframework.security.ui.basicauth.BasicProcessingFilter;
import org.springframework.security.ui.logout.LogoutFilter;
@@ -56,7 +57,7 @@ public class HttpSecurityBeanDefinitionParserTests {
@Test
public void httpAutoConfigSetsUpCorrectFilterList() {
- setContext("" + AUTH_PROVIDER_XML);
+ setContext("" + AUTH_PROVIDER_XML);
FilterChainProxy filterChainProxy = getFilterChainProxy();
@@ -66,11 +67,12 @@ public class HttpSecurityBeanDefinitionParserTests {
}
private void checkAutoConfigFilters(List filterList) {
- assertEquals("Expected 10 filters in chain", 10, filterList.size());
+ assertEquals("Expected 11 filters in chain", 11, filterList.size());
Iterator filters = filterList.iterator();
assertTrue(filters.next() instanceof HttpSessionContextIntegrationFilter);
+ assertTrue(filters.next() instanceof SessionFixationProtectionFilter);
assertTrue(filters.next() instanceof LogoutFilter);
assertTrue(filters.next() instanceof AuthenticationProcessingFilter);
assertTrue(filters.next() instanceof DefaultLoginPageGeneratingFilter);
@@ -185,7 +187,7 @@ public class HttpSecurityBeanDefinitionParserTests {
List filters = filterChainProxy.getFilters("/someurl");
- assertEquals("Expected 11 filters in chain", 11, filters.size());
+ assertEquals("Expected 12 filters in chain", 12, filters.size());
assertTrue(filters.get(0) instanceof ChannelProcessingFilter);
}
@@ -216,7 +218,7 @@ public class HttpSecurityBeanDefinitionParserTests {
"");
List filters = getFilterChainProxy().getFilters("/someurl");
- assertEquals(11, filters.size());
+ assertEquals(12, filters.size());
assertTrue(filters.get(1) instanceof OrderedFilterBeanDefinitionDecorator.OrderedFilterDecorator);
assertEquals("userFilter", ((OrderedFilterBeanDefinitionDecorator.OrderedFilterDecorator)filters.get(1)).getBeanName());
}
@@ -242,9 +244,18 @@ public class HttpSecurityBeanDefinitionParserTests {
"" + AUTH_PROVIDER_XML);
List filters = getFilterChainProxy().getFilters("/someurl");
- assertTrue(filters.get(2) instanceof X509PreAuthenticatedProcessingFilter);
+ assertTrue(filters.get(3) instanceof X509PreAuthenticatedProcessingFilter);
}
+ @Test
+ public void disablingSessionProtectionRemovesFilter() throws Exception {
+ setContext(
+ "" + AUTH_PROVIDER_XML);
+ List filters = getFilterChainProxy().getFilters("/someurl");
+
+ assertFalse(filters.get(1) instanceof SessionFixationProtectionFilter);
+ }
+
private void setContext(String context) {
appContext = new InMemoryXmlApplicationContext(context);
}