diff --git a/config/src/main/java/org/springframework/security/config/http/RememberMeBeanDefinitionParser.java b/config/src/main/java/org/springframework/security/config/http/RememberMeBeanDefinitionParser.java
index 737c7818d9..d6ab05c12e 100644
--- a/config/src/main/java/org/springframework/security/config/http/RememberMeBeanDefinitionParser.java
+++ b/config/src/main/java/org/springframework/security/config/http/RememberMeBeanDefinitionParser.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2013 the original author or authors.
+ * Copyright 2002-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -50,6 +50,7 @@ class RememberMeBeanDefinitionParser implements BeanDefinitionParser {
static final String ATT_TOKEN_VALIDITY = "token-validity-seconds";
static final String ATT_SECURE_COOKIE = "use-secure-cookie";
static final String ATT_FORM_REMEMBERME_PARAMETER = "remember-me-parameter";
+ static final String ATT_REMEMBERME_COOKIE = "remember-me-cookie";
protected final Log logger = LogFactory.getLog(getClass());
private final String key;
@@ -74,6 +75,7 @@ class RememberMeBeanDefinitionParser implements BeanDefinitionParser {
String tokenValiditySeconds = element.getAttribute(ATT_TOKEN_VALIDITY);
String useSecureCookie = element.getAttribute(ATT_SECURE_COOKIE);
String remembermeParameter = element.getAttribute(ATT_FORM_REMEMBERME_PARAMETER);
+ String remembermeCookie = element.getAttribute(ATT_REMEMBERME_COOKIE);
Object source = pc.extractSource(element);
RootBeanDefinition services = null;
@@ -85,11 +87,12 @@ class RememberMeBeanDefinitionParser implements BeanDefinitionParser {
boolean useSecureCookieSet = StringUtils.hasText(useSecureCookie);
boolean tokenValiditySet = StringUtils.hasText(tokenValiditySeconds);
boolean remembermeParameterSet = StringUtils.hasText(remembermeParameter);
+ boolean remembermeCookieSet = StringUtils.hasText(remembermeCookie);
- if (servicesRefSet && (dataSourceSet || tokenRepoSet || userServiceSet || tokenValiditySet || useSecureCookieSet || remembermeParameterSet)) {
+ if (servicesRefSet && (dataSourceSet || tokenRepoSet || userServiceSet || tokenValiditySet || useSecureCookieSet || remembermeParameterSet || remembermeCookieSet)) {
pc.getReaderContext().error(ATT_SERVICES_REF + " can't be used in combination with attributes "
+ ATT_TOKEN_REPOSITORY + "," + ATT_DATA_SOURCE + ", " + ATT_USER_SERVICE_REF + ", " + ATT_TOKEN_VALIDITY
- + ", " + ATT_SECURE_COOKIE + " or " + ATT_FORM_REMEMBERME_PARAMETER, source);
+ + ", " + ATT_SECURE_COOKIE + ", " + ATT_FORM_REMEMBERME_PARAMETER + " or " + ATT_REMEMBERME_COOKIE, source);
}
if (dataSourceSet && tokenRepoSet) {
@@ -144,6 +147,10 @@ class RememberMeBeanDefinitionParser implements BeanDefinitionParser {
services.getPropertyValues().addPropertyValue("parameter", remembermeParameter);
}
+ if (remembermeCookieSet) {
+ services.getPropertyValues().addPropertyValue("cookieName", remembermeCookie);
+ }
+
services.setSource(source);
servicesName = pc.getReaderContext().generateBeanName(services);
pc.registerBeanComponent(new BeanComponentDefinition(services, servicesName));
diff --git a/config/src/main/resources/org/springframework/security/config/spring-security-4.0.rnc b/config/src/main/resources/org/springframework/security/config/spring-security-4.0.rnc
index 44657d7479..d59cbbbab1 100644
--- a/config/src/main/resources/org/springframework/security/config/spring-security-4.0.rnc
+++ b/config/src/main/resources/org/springframework/security/config/spring-security-4.0.rnc
@@ -586,6 +586,9 @@ remember-me.attlist &=
remember-me.attlist &=
## The name of the request parameter which toggles remember-me authentication. Defaults to '_spring_security_remember_me'.
attribute remember-me-parameter {xsd:token}?
+remember-me.attlist &=
+ ## The name of cookie which store the token for remember-me authentication. Defaults to 'SPRING_SECURITY_REMEMBER_ME_COOKIE'.
+ attribute remember-me-cookie {xsd:token}?
token-repository-ref =
## Reference to a PersistentTokenRepository bean for use with the persistent token remember-me implementation.
diff --git a/config/src/main/resources/org/springframework/security/config/spring-security-4.0.xsd b/config/src/main/resources/org/springframework/security/config/spring-security-4.0.xsd
index e8a014d829..413dda3347 100644
--- a/config/src/main/resources/org/springframework/security/config/spring-security-4.0.xsd
+++ b/config/src/main/resources/org/springframework/security/config/spring-security-4.0.xsd
@@ -1827,6 +1827,13 @@
+
+
+ The name of cookie which store the token for remember-me authentication. Defaults to
+ 'SPRING_SECURITY_REMEMBER_ME_COOKIE'.
+
+
+
diff --git a/config/src/test/groovy/org/springframework/security/config/http/RememberMeConfigTests.groovy b/config/src/test/groovy/org/springframework/security/config/http/RememberMeConfigTests.groovy
index 9c5c38f5f4..5f29b6c301 100644
--- a/config/src/test/groovy/org/springframework/security/config/http/RememberMeConfigTests.groovy
+++ b/config/src/test/groovy/org/springframework/security/config/http/RememberMeConfigTests.groovy
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2013 the original author or authors.
+ * Copyright 2002-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -277,6 +277,31 @@ class RememberMeConfigTests extends AbstractHttpConfigTests {
BeanDefinitionParsingException e = thrown()
}
+ // SEC-2826
+ def 'Custom remember-me-cookie is supported'() {
+ httpAutoConfig () {
+ 'remember-me'('remember-me-cookie': 'ourCookie')
+ }
+
+ createAppContext(AUTH_PROVIDER_XML)
+ expect:
+ rememberMeServices().cookieName == 'ourCookie'
+ }
+
+ // SEC-2826
+ def 'remember-me-cookie cannot be used together with services-ref'() {
+ when:
+ httpAutoConfig () {
+ 'remember-me'('remember-me-cookie': 'ourCookie', 'services-ref': 'ourService')
+ }
+
+ createAppContext(AUTH_PROVIDER_XML)
+ then:
+ BeanDefinitionParsingException e = thrown()
+ expect:
+ e.message == 'Configuration problem: services-ref can\'t be used in combination with attributes token-repository-ref,data-source-ref, user-service-ref, token-validity-seconds, use-secure-cookie, remember-me-parameter or remember-me-cookie\nOffending resource: null'
+ }
+
def rememberMeServices() {
getFilter(RememberMeAuthenticationFilter.class).getRememberMeServices()
}
diff --git a/docs/manual/src/docs/asciidoc/index.adoc b/docs/manual/src/docs/asciidoc/index.adoc
index bb4beb30b8..30c6a8dfc9 100644
--- a/docs/manual/src/docs/asciidoc/index.adoc
+++ b/docs/manual/src/docs/asciidoc/index.adoc
@@ -7594,6 +7594,11 @@ A reference to a `DataSource` bean. If this is set, `PersistentTokenBasedRemembe
The name of the request parameter which toggles remember-me authentication. Defaults to "_spring_security_remember_me". Maps to the "parameter" property of `AbstractRememberMeServices`.
+[[nsa-remember-me-remember-me-cookie]]
+* **remember-me-cookie**
+The name of cookie which store the token for remember-me authentication. Defaults to "SPRING_SECURITY_REMEMBER_ME_COOKIE". Maps to the "cookieName" property of `AbstractRememberMeServices`.
+
+
[[nsa-remember-me-key]]
* **key**
Maps to the "key" property of `AbstractRememberMeServices`. Should be set to a unique value to ensure that remember-me cookies are only valid within the one application footnote:[