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
deleted file mode 100644
index 7217cd1166..0000000000
--- a/config/src/test/groovy/org/springframework/security/config/http/RememberMeConfigTests.groovy
+++ /dev/null
@@ -1,312 +0,0 @@
-/*
- * 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.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.springframework.security.config.http
-
-import static org.springframework.security.config.ConfigTestUtils.AUTH_PROVIDER_XML
-
-import javax.sql.DataSource
-
-import org.springframework.beans.FatalBeanException
-import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer
-import org.springframework.beans.factory.parsing.BeanDefinitionParsingException
-import org.springframework.security.TestDataSource
-import org.springframework.security.authentication.ProviderManager
-import org.springframework.security.authentication.RememberMeAuthenticationProvider
-import org.springframework.security.core.userdetails.MockUserDetailsService
-import org.springframework.security.util.FieldUtils
-import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler
-import org.springframework.security.web.authentication.logout.LogoutFilter
-import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler
-import org.springframework.security.web.authentication.rememberme.AbstractRememberMeServices
-import org.springframework.security.web.authentication.rememberme.InMemoryTokenRepositoryImpl
-import org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl
-import org.springframework.security.web.authentication.rememberme.PersistentTokenBasedRememberMeServices
-import org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter
-import org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices
-
-/**
- *
- * @author Luke Taylor
- * @author Rob Winch
- * @author Oliver Becker
- */
-class RememberMeConfigTests extends AbstractHttpConfigTests {
-
- def rememberMeServiceWorksWithTokenRepoRef() {
- httpAutoConfig () {
- 'remember-me'('token-repository-ref': 'tokenRepo')
- }
- bean('tokenRepo', CustomTokenRepository.class.name)
-
- createAppContext(AUTH_PROVIDER_XML)
-
- def rememberMeServices = rememberMeServices()
-
- expect:
- rememberMeServices instanceof PersistentTokenBasedRememberMeServices
- rememberMeServices.tokenRepository instanceof CustomTokenRepository
- FieldUtils.getFieldValue(rememberMeServices, "useSecureCookie") == null
- }
-
- def rememberMeServiceWorksWithDataSourceRef() {
- httpAutoConfig () {
- 'remember-me'('data-source-ref': 'ds')
- }
- bean('ds', TestDataSource.class.name, ['tokendb'])
-
- createAppContext(AUTH_PROVIDER_XML)
-
- def rememberMeServices = rememberMeServices()
-
- expect:
- rememberMeServices instanceof PersistentTokenBasedRememberMeServices
- rememberMeServices.tokenRepository instanceof JdbcTokenRepositoryImpl
- }
-
- def rememberMeServiceWorksWithAuthenticationSuccessHandlerRef() {
- httpAutoConfig () {
- 'remember-me'('authentication-success-handler-ref': 'sh')
- }
- bean('sh', SimpleUrlAuthenticationSuccessHandler.class.name, ['/target'])
-
- createAppContext(AUTH_PROVIDER_XML)
-
- expect:
- getFilter(RememberMeAuthenticationFilter.class).successHandler instanceof SimpleUrlAuthenticationSuccessHandler
- }
-
- def rememberMeServiceWorksWithExternalServicesImpl() {
- httpAutoConfig () {
- 'remember-me'('key': "#{'our' + 'key'}", 'services-ref': 'rms')
- csrf(disabled:true)
- }
- xml.'b:bean'(id: 'rms', 'class': TokenBasedRememberMeServices.class.name) {
- 'b:constructor-arg'(value: 'ourKey')
- 'b:constructor-arg'(ref: 'us')
- 'b:property'(name: 'tokenValiditySeconds', value: '5000')
- }
-
- createAppContext(AUTH_PROVIDER_XML)
-
- List logoutHandlers = FieldUtils.getFieldValue(getFilter(LogoutFilter.class), "handler").logoutHandlers;
- Map ams = appContext.getBeansOfType(ProviderManager.class);
- ProviderManager am = (ams.values() as List).find { it instanceof ProviderManager && it.providers.size() == 2}
- RememberMeAuthenticationProvider rmp = am.providers.find { it instanceof RememberMeAuthenticationProvider}
-
- expect:
- rmp != null
- 5000 == FieldUtils.getFieldValue(rememberMeServices(), "tokenValiditySeconds")
- // SEC-909
- logoutHandlers.size() == 2
- logoutHandlers.get(1) == rememberMeServices()
- // SEC-1281
- rmp.key == "ourkey"
- }
-
- def rememberMeAddsLogoutHandlerToLogoutFilter() {
- httpAutoConfig () {
- 'remember-me'()
- csrf(disabled:true)
- }
- createAppContext(AUTH_PROVIDER_XML)
-
- def rememberMeServices = rememberMeServices()
- List logoutHandlers = getFilter(LogoutFilter.class).handler.logoutHandlers
-
- expect:
- rememberMeServices
- logoutHandlers.size() == 2
- logoutHandlers.get(0) instanceof SecurityContextLogoutHandler
- logoutHandlers.get(1) == rememberMeServices
- }
-
- def rememberMeTokenValidityIsParsedCorrectly() {
- httpAutoConfig () {
- 'remember-me'('key': 'ourkey', 'token-validity-seconds':'10000')
- }
-
- createAppContext(AUTH_PROVIDER_XML)
-
- def rememberMeServices = rememberMeServices()
- def rememberMeFilter = getFilter(RememberMeAuthenticationFilter.class)
-
- expect:
- rememberMeFilter.authenticationManager
- rememberMeServices.key == 'ourkey'
- rememberMeServices.tokenValiditySeconds == 10000
- rememberMeServices.userDetailsService
- }
-
- def 'Remember-me token validity allows negative value for non-persistent implementation'() {
- httpAutoConfig () {
- 'remember-me'('key': 'ourkey', 'token-validity-seconds':'-1')
- }
-
- createAppContext(AUTH_PROVIDER_XML)
- expect:
- rememberMeServices().tokenValiditySeconds == -1
- }
-
- def 'remember-me@token-validity-seconds denies for persistent implementation'() {
- setup:
- httpAutoConfig () {
- 'remember-me'('key': 'ourkey', 'token-validity-seconds':'-1', 'dataSource' : 'dataSource')
- }
- mockBean(DataSource)
- when:
- createAppContext(AUTH_PROVIDER_XML)
- then:
- thrown(FatalBeanException)
- }
-
- def 'SEC-2165: remember-me@token-validity-seconds allows property placeholders'() {
- when:
- httpAutoConfig () {
- 'remember-me'('key': 'ourkey', 'token-validity-seconds':'${security.rememberme.ttl}')
- }
- xml.'b:bean'(class: PropertyPlaceholderConfigurer.name) {
- 'b:property'(name:'properties', value:'security.rememberme.ttl=30')
- }
-
- createAppContext(AUTH_PROVIDER_XML)
- then:
- rememberMeServices().tokenValiditySeconds == 30
- }
-
- def rememberMeSecureCookieAttributeIsSetCorrectly() {
- httpAutoConfig () {
- 'remember-me'('key': 'ourkey', 'use-secure-cookie':'true')
- }
-
- createAppContext(AUTH_PROVIDER_XML)
- expect:
- FieldUtils.getFieldValue(rememberMeServices(), "useSecureCookie")
- }
-
- // SEC-1827
- def rememberMeSecureCookieAttributeFalse() {
- httpAutoConfig () {
- 'remember-me'('key': 'ourkey', 'use-secure-cookie':'false')
- }
-
- createAppContext(AUTH_PROVIDER_XML)
- expect: 'useSecureCookie is false'
- FieldUtils.getFieldValue(rememberMeServices(), "useSecureCookie") == Boolean.FALSE
- }
-
- def 'Negative token-validity is rejected with persistent implementation'() {
- when:
- httpAutoConfig () {
- 'remember-me'('key': 'ourkey', 'token-validity-seconds':'-1', 'token-repository-ref': 'tokenRepo')
- }
- bean('tokenRepo', InMemoryTokenRepositoryImpl.class.name)
- createAppContext(AUTH_PROVIDER_XML)
-
- then:
- BeanDefinitionParsingException e = thrown()
- }
-
- def 'Custom user service is supported'() {
- when:
- httpAutoConfig () {
- 'remember-me'('key': 'ourkey', 'token-validity-seconds':'-1', 'user-service-ref': 'userService')
- }
- bean('userService', MockUserDetailsService.class.name)
- createAppContext(AUTH_PROVIDER_XML)
-
- then: "Parses OK"
- notThrown BeanDefinitionParsingException
- }
-
- // SEC-742
- def rememberMeWorksWithoutBasicProcessingFilter() {
- when:
- xml.http () {
- 'form-login'('login-page': '/login.jsp', 'default-target-url': '/messageList.html' )
- logout('logout-success-url': '/login.jsp')
- anonymous(username: 'guest', 'granted-authority': 'guest')
- 'remember-me'()
- }
- createAppContext(AUTH_PROVIDER_XML)
-
- then: "Parses OK"
- notThrown BeanDefinitionParsingException
- }
-
- def 'Default remember-me-parameter is correct'() {
- httpAutoConfig () {
- 'remember-me'()
- }
-
- createAppContext(AUTH_PROVIDER_XML)
- expect:
- rememberMeServices().parameter == AbstractRememberMeServices.DEFAULT_PARAMETER
- }
-
- // SEC-2119
- def 'Custom remember-me-parameter is supported'() {
- httpAutoConfig () {
- 'remember-me'('remember-me-parameter': 'ourParam')
- }
-
- createAppContext(AUTH_PROVIDER_XML)
- expect:
- rememberMeServices().parameter == 'ourParam'
- }
-
- def 'remember-me-parameter cannot be used together with services-ref'() {
- when:
- httpAutoConfig () {
- 'remember-me'('remember-me-parameter': 'ourParam', 'services-ref': 'ourService')
- }
- createAppContext(AUTH_PROVIDER_XML)
- then:
- 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()
- }
-
- static class CustomTokenRepository extends InMemoryTokenRepositoryImpl {
-
- }
-}
diff --git a/config/src/test/java/org/springframework/security/config/http/RememberMeConfigTests.java b/config/src/test/java/org/springframework/security/config/http/RememberMeConfigTests.java
new file mode 100644
index 0000000000..b1983250ab
--- /dev/null
+++ b/config/src/test/java/org/springframework/security/config/http/RememberMeConfigTests.java
@@ -0,0 +1,378 @@
+/*
+ * Copyright 2002-2018 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springframework.security.config.http;
+
+import java.util.Collections;
+import javax.servlet.http.Cookie;
+
+import org.junit.Rule;
+import org.junit.Test;
+
+import org.springframework.beans.FatalBeanException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.parsing.BeanDefinitionParsingException;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.security.TestDataSource;
+import org.springframework.security.config.test.SpringTestRule;
+import org.springframework.security.core.userdetails.User;
+import org.springframework.security.core.userdetails.UserDetailsService;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.MvcResult;
+import org.springframework.test.web.servlet.ResultActions;
+import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatCode;
+import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf;
+import static org.springframework.security.web.authentication.rememberme.AbstractRememberMeServices.DEFAULT_PARAMETER;
+import static org.springframework.security.web.authentication.rememberme.AbstractRememberMeServices.SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY;
+import static org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl.CREATE_TABLE_SQL;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.cookie;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrl;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+/**
+ *
+ * @author Luke Taylor
+ * @author Rob Winch
+ * @author Oliver Becker
+ */
+public class RememberMeConfigTests {
+ private static final String CONFIG_LOCATION_PREFIX =
+ "classpath:org/springframework/security/config/http/RememberMeConfigTests";
+
+ @Autowired
+ MockMvc mvc;
+
+ @Rule
+ public final SpringTestRule spring = new SpringTestRule();
+
+ @Test
+ public void requestWithRememberMeWhenUsingCustomTokenRepositoryThenAutomaticallyReauthenticates()
+ throws Exception {
+
+ this.spring.configLocations(this.xml("WithTokenRepository")).autowire();
+
+ MvcResult result = this.rememberAuthentication("user", "password")
+ .andExpect(cookie().secure(SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY, false))
+ .andReturn();
+
+ Cookie cookie = rememberMeCookie(result);
+
+ this.mvc.perform(get("/authenticated")
+ .cookie(cookie))
+ .andExpect(status().isOk());
+
+ JdbcTemplate template = this.spring.getContext().getBean(JdbcTemplate.class);
+ int count = template.queryForObject("select count(*) from persistent_logins", int.class);
+ assertThat(count).isEqualTo(1);
+ }
+
+ @Test
+ public void requestWithRememberMeWhenUsingCustomDataSourceThenAutomaticallyReauthenticates()
+ throws Exception {
+
+ this.spring.configLocations(this.xml("WithDataSource")).autowire();
+
+ TestDataSource dataSource = this.spring.getContext().getBean(TestDataSource.class);
+ JdbcTemplate template = new JdbcTemplate(dataSource);
+ template.execute(CREATE_TABLE_SQL);
+
+ MvcResult result = this.rememberAuthentication("user", "password")
+ .andExpect(cookie().secure(SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY, false))
+ .andReturn();
+
+ Cookie cookie = rememberMeCookie(result);
+
+ this.mvc.perform(get("/authenticated")
+ .cookie(cookie))
+ .andExpect(status().isOk());
+
+ int count = template.queryForObject("select count(*) from persistent_logins", int.class);
+ assertThat(count).isEqualTo(1);
+ }
+
+ @Test
+ public void requestWithRememberMeWhenUsingAuthenticationSuccessHandlerThenInvokesHandler()
+ throws Exception {
+
+ this.spring.configLocations(this.xml("WithAuthenticationSuccessHandler")).autowire();
+
+ TestDataSource dataSource = this.spring.getContext().getBean(TestDataSource.class);
+ JdbcTemplate template = new JdbcTemplate(dataSource);
+ template.execute(CREATE_TABLE_SQL);
+
+ MvcResult result = this.rememberAuthentication("user", "password")
+ .andExpect(cookie().secure(SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY, false))
+ .andReturn();
+
+ Cookie cookie = rememberMeCookie(result);
+
+ this.mvc.perform(get("/authenticated")
+ .cookie(cookie))
+ .andExpect(redirectedUrl("/target"));
+
+ int count = template.queryForObject("select count(*) from persistent_logins", int.class);
+ assertThat(count).isEqualTo(1);
+ }
+
+ @Test
+ public void requestWithRememberMeWhenUsingCustomRememberMeServicesThenAuthenticates()
+ throws Exception {
+ // SEC-1281 - using key with external services
+ this.spring.configLocations(this.xml("WithServicesRef")).autowire();
+
+ MvcResult result = this.rememberAuthentication("user", "password")
+ .andExpect(cookie().secure(SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY, false))
+ .andExpect(cookie().maxAge(SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY, 5000))
+ .andReturn();
+
+ Cookie cookie = rememberMeCookie(result);
+
+ this.mvc.perform(get("/authenticated")
+ .cookie(cookie))
+ .andExpect(status().isOk());
+
+ // SEC-909
+ this.mvc.perform(post("/logout")
+ .cookie(cookie)
+ .with(csrf()))
+ .andExpect(cookie().maxAge(SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY, 0))
+ .andReturn();
+ }
+
+ @Test
+ public void logoutWhenUsingRememberMeDefaultsThenCookieIsCancelled()
+ throws Exception {
+
+ this.spring.configLocations(this.xml("DefaultConfig")).autowire();
+
+ MvcResult result = this.rememberAuthentication("user", "password").andReturn();
+
+ Cookie cookie = rememberMeCookie(result);
+
+ this.mvc.perform(post("/logout")
+ .cookie(cookie)
+ .with(csrf()))
+ .andExpect(cookie().maxAge(SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY, 0));
+ }
+
+ @Test
+ public void requestWithRememberMeWhenTokenValidityIsConfiguredThenCookieReflectsCorrectExpiration()
+ throws Exception {
+
+ this.spring.configLocations(this.xml("TokenValidity")).autowire();
+
+ MvcResult result = this.rememberAuthentication("user", "password")
+ .andExpect(cookie().maxAge(SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY, 10000))
+ .andReturn();
+
+ Cookie cookie = rememberMeCookie(result);
+
+ this.mvc.perform(get("/authenticated")
+ .cookie(cookie))
+ .andExpect(status().isOk());
+ }
+
+ @Test
+ public void requestWithRememberMeWhenTokenValidityIsNegativeThenCookieReflectsCorrectExpiration()
+ throws Exception {
+
+ this.spring.configLocations(this.xml("NegativeTokenValidity")).autowire();
+
+ this.rememberAuthentication("user", "password")
+ .andExpect(cookie().maxAge(SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY, -1));
+ }
+
+
+ @Test
+ public void configureWhenUsingDataSourceAndANegativeTokenValidityThenThrowsWiringException() {
+ assertThatCode(() -> this.spring.configLocations(this.xml("NegativeTokenValidityWithDataSource")).autowire())
+ .isInstanceOf(FatalBeanException.class);
+ }
+
+ @Test
+ public void requestWithRememberMeWhenTokenValidityIsResolvedByPropertyPlaceholderThenCookieReflectsCorrectExpiration()
+ throws Exception {
+
+ this.spring.configLocations(this.xml("Sec2165")).autowire();
+
+ this.rememberAuthentication("user", "password")
+ .andExpect(cookie().maxAge(SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY, 30));
+ }
+
+ @Test
+ public void requestWithRememberMeWhenUseSecureCookieIsTrueThenCookieIsSecure()
+ throws Exception {
+
+ this.spring.configLocations(this.xml("SecureCookie")).autowire();
+
+ this.rememberAuthentication("user", "password")
+ .andExpect(cookie().secure(SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY, true));
+ }
+
+ /**
+ * SEC-1827
+ */
+ @Test
+ public void requestWithRememberMeWhenUseSecureCookieIsFalseThenCookieIsNotSecure()
+ throws Exception {
+
+ this.spring.configLocations(this.xml("Sec1827")).autowire();
+
+ this.rememberAuthentication("user", "password")
+ .andExpect(cookie().secure(SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY, false));
+ }
+
+ @Test
+ public void configureWhenUsingPersistentTokenRepositoryAndANegativeTokenValidityThenThrowsWiringException() {
+ assertThatCode(() -> this.spring.configLocations(this.xml("NegativeTokenValidityWithPersistentRepository")).autowire())
+ .isInstanceOf(BeanDefinitionParsingException.class);
+ }
+
+ @Test
+ public void requestWithRememberMeWhenUsingCustomUserDetailsServiceThenInvokesThisUserDetailsService()
+ throws Exception {
+ this.spring.configLocations(this.xml("WithUserDetailsService")).autowire();
+
+ UserDetailsService userDetailsService = this.spring.getContext().getBean(UserDetailsService.class);
+ when(userDetailsService.loadUserByUsername("user")).thenAnswer((invocation) ->
+ new User("user", "{noop}password", Collections.emptyList()));
+
+ MvcResult result = this.rememberAuthentication("user", "password").andReturn();
+
+ Cookie cookie = rememberMeCookie(result);
+
+ this.mvc.perform(get("/authenticated")
+ .cookie(cookie))
+ .andExpect(status().isOk());
+
+ verify(userDetailsService, atLeastOnce()).loadUserByUsername("user");
+ }
+
+ /**
+ * SEC-742
+ */
+ @Test
+ public void requestWithRememberMeWhenExcludingBasicAuthenticationFilterThenStillReauthenticates()
+ throws Exception {
+
+ this.spring.configLocations(this.xml("Sec742")).autowire();
+
+ MvcResult result =
+ this.mvc.perform(login("user", "password")
+ .param("remember-me", "true")
+ .with(csrf()))
+ .andExpect(redirectedUrl("/messageList.html"))
+ .andReturn();
+
+ Cookie cookie = rememberMeCookie(result);
+
+ this.mvc.perform(get("/authenticated")
+ .cookie(cookie))
+ .andExpect(status().isOk());
+ }
+
+ /**
+ * SEC-2119
+ */
+ @Test
+ public void requestWithRememberMeWhenUsingCustomRememberMeParameterThenReauthenticates()
+ throws Exception {
+
+ this.spring.configLocations(this.xml("WithRememberMeParameter")).autowire();
+
+ MvcResult result =
+ this.mvc.perform(login("user", "password")
+ .param("custom-remember-me-parameter", "true")
+ .with(csrf()))
+ .andExpect(redirectedUrl("/"))
+ .andReturn();
+
+ Cookie cookie = rememberMeCookie(result);
+
+ this.mvc.perform(get("/authenticated")
+ .cookie(cookie))
+ .andExpect(status().isOk());
+ }
+
+ @Test
+ public void configureWhenUsingRememberMeParameterAndServicesRefThenThrowsWiringException() {
+ assertThatCode(() -> this.spring.configLocations(this.xml("WithRememberMeParameterAndServicesRef")).autowire())
+ .isInstanceOf(BeanDefinitionParsingException.class);
+ }
+
+ /**
+ * SEC-2826
+ */
+ @Test
+ public void authenticateWhenUsingCustomRememberMeCookieNameThenIssuesCookieWithThatName()
+ throws Exception {
+
+ this.spring.configLocations(this.xml("WithRememberMeCookie")).autowire();
+
+ this.rememberAuthentication("user", "password")
+ .andExpect(cookie().exists("custom-remember-me-cookie"));
+ }
+
+ /**
+ * SEC-2826
+ */
+ @Test
+ public void configureWhenUsingRememberMeCookieAndServicesRefThenThrowsWiringException() {
+ assertThatCode(() -> this.spring.configLocations(this.xml("WithRememberMeCookieAndServicesRef")).autowire())
+ .isInstanceOf(BeanDefinitionParsingException.class)
+ .hasMessageContaining("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");
+ }
+
+ @RestController
+ static class BasicController {
+ @GetMapping("/authenticated")
+ String ok() {
+ return "ok";
+ }
+ }
+
+ private ResultActions rememberAuthentication(String username, String password)
+ throws Exception {
+
+ return this.mvc.perform(login(username, password)
+ .param(DEFAULT_PARAMETER, "true")
+ .with(csrf()))
+ .andExpect(redirectedUrl("/"));
+ }
+
+ private static MockHttpServletRequestBuilder login(String username, String password) {
+ return post("/login").param("username", username).param("password", password);
+ }
+
+ private static Cookie rememberMeCookie(MvcResult result) {
+ return result.getResponse().getCookie("remember-me");
+ }
+
+ private String xml(String configName) {
+ return CONFIG_LOCATION_PREFIX + "-" + configName + ".xml";
+ }
+}
diff --git a/config/src/test/resources/org/springframework/security/config/http/RememberMeConfigTests-DefaultConfig.xml b/config/src/test/resources/org/springframework/security/config/http/RememberMeConfigTests-DefaultConfig.xml
new file mode 100644
index 0000000000..b59915244a
--- /dev/null
+++ b/config/src/test/resources/org/springframework/security/config/http/RememberMeConfigTests-DefaultConfig.xml
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/config/src/test/resources/org/springframework/security/config/http/RememberMeConfigTests-NegativeTokenValidity.xml b/config/src/test/resources/org/springframework/security/config/http/RememberMeConfigTests-NegativeTokenValidity.xml
new file mode 100644
index 0000000000..ced04be82d
--- /dev/null
+++ b/config/src/test/resources/org/springframework/security/config/http/RememberMeConfigTests-NegativeTokenValidity.xml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/config/src/test/resources/org/springframework/security/config/http/RememberMeConfigTests-NegativeTokenValidityWithDataSource.xml b/config/src/test/resources/org/springframework/security/config/http/RememberMeConfigTests-NegativeTokenValidityWithDataSource.xml
new file mode 100644
index 0000000000..a650cda5f6
--- /dev/null
+++ b/config/src/test/resources/org/springframework/security/config/http/RememberMeConfigTests-NegativeTokenValidityWithDataSource.xml
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/config/src/test/resources/org/springframework/security/config/http/RememberMeConfigTests-NegativeTokenValidityWithPersistentRepository.xml b/config/src/test/resources/org/springframework/security/config/http/RememberMeConfigTests-NegativeTokenValidityWithPersistentRepository.xml
new file mode 100644
index 0000000000..ff41dc27cb
--- /dev/null
+++ b/config/src/test/resources/org/springframework/security/config/http/RememberMeConfigTests-NegativeTokenValidityWithPersistentRepository.xml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/config/src/test/resources/org/springframework/security/config/http/RememberMeConfigTests-Sec1827.xml b/config/src/test/resources/org/springframework/security/config/http/RememberMeConfigTests-Sec1827.xml
new file mode 100644
index 0000000000..76076025d9
--- /dev/null
+++ b/config/src/test/resources/org/springframework/security/config/http/RememberMeConfigTests-Sec1827.xml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/config/src/test/resources/org/springframework/security/config/http/RememberMeConfigTests-Sec2165.xml b/config/src/test/resources/org/springframework/security/config/http/RememberMeConfigTests-Sec2165.xml
new file mode 100644
index 0000000000..7874a9bfe3
--- /dev/null
+++ b/config/src/test/resources/org/springframework/security/config/http/RememberMeConfigTests-Sec2165.xml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/config/src/test/resources/org/springframework/security/config/http/RememberMeConfigTests-Sec742.xml b/config/src/test/resources/org/springframework/security/config/http/RememberMeConfigTests-Sec742.xml
new file mode 100644
index 0000000000..6d58d63ba5
--- /dev/null
+++ b/config/src/test/resources/org/springframework/security/config/http/RememberMeConfigTests-Sec742.xml
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/config/src/test/resources/org/springframework/security/config/http/RememberMeConfigTests-SecureCookie.xml b/config/src/test/resources/org/springframework/security/config/http/RememberMeConfigTests-SecureCookie.xml
new file mode 100644
index 0000000000..1c59a2c653
--- /dev/null
+++ b/config/src/test/resources/org/springframework/security/config/http/RememberMeConfigTests-SecureCookie.xml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/config/src/test/resources/org/springframework/security/config/http/RememberMeConfigTests-TokenValidity.xml b/config/src/test/resources/org/springframework/security/config/http/RememberMeConfigTests-TokenValidity.xml
new file mode 100644
index 0000000000..9517b3a791
--- /dev/null
+++ b/config/src/test/resources/org/springframework/security/config/http/RememberMeConfigTests-TokenValidity.xml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/config/src/test/resources/org/springframework/security/config/http/RememberMeConfigTests-WithAuthenticationSuccessHandler.xml b/config/src/test/resources/org/springframework/security/config/http/RememberMeConfigTests-WithAuthenticationSuccessHandler.xml
new file mode 100644
index 0000000000..360d2004a7
--- /dev/null
+++ b/config/src/test/resources/org/springframework/security/config/http/RememberMeConfigTests-WithAuthenticationSuccessHandler.xml
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/config/src/test/resources/org/springframework/security/config/http/RememberMeConfigTests-WithDataSource.xml b/config/src/test/resources/org/springframework/security/config/http/RememberMeConfigTests-WithDataSource.xml
new file mode 100644
index 0000000000..1c0834a88b
--- /dev/null
+++ b/config/src/test/resources/org/springframework/security/config/http/RememberMeConfigTests-WithDataSource.xml
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/config/src/test/resources/org/springframework/security/config/http/RememberMeConfigTests-WithRememberMeCookie.xml b/config/src/test/resources/org/springframework/security/config/http/RememberMeConfigTests-WithRememberMeCookie.xml
new file mode 100644
index 0000000000..5e101d025b
--- /dev/null
+++ b/config/src/test/resources/org/springframework/security/config/http/RememberMeConfigTests-WithRememberMeCookie.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/config/src/test/resources/org/springframework/security/config/http/RememberMeConfigTests-WithRememberMeCookieAndServicesRef.xml b/config/src/test/resources/org/springframework/security/config/http/RememberMeConfigTests-WithRememberMeCookieAndServicesRef.xml
new file mode 100644
index 0000000000..bcc013e76d
--- /dev/null
+++ b/config/src/test/resources/org/springframework/security/config/http/RememberMeConfigTests-WithRememberMeCookieAndServicesRef.xml
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/config/src/test/resources/org/springframework/security/config/http/RememberMeConfigTests-WithRememberMeParameter.xml b/config/src/test/resources/org/springframework/security/config/http/RememberMeConfigTests-WithRememberMeParameter.xml
new file mode 100644
index 0000000000..94d8cf8c71
--- /dev/null
+++ b/config/src/test/resources/org/springframework/security/config/http/RememberMeConfigTests-WithRememberMeParameter.xml
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/config/src/test/resources/org/springframework/security/config/http/RememberMeConfigTests-WithRememberMeParameterAndServicesRef.xml b/config/src/test/resources/org/springframework/security/config/http/RememberMeConfigTests-WithRememberMeParameterAndServicesRef.xml
new file mode 100644
index 0000000000..46dff530c6
--- /dev/null
+++ b/config/src/test/resources/org/springframework/security/config/http/RememberMeConfigTests-WithRememberMeParameterAndServicesRef.xml
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/config/src/test/resources/org/springframework/security/config/http/RememberMeConfigTests-WithServicesRef.xml b/config/src/test/resources/org/springframework/security/config/http/RememberMeConfigTests-WithServicesRef.xml
new file mode 100644
index 0000000000..682cd2c3ea
--- /dev/null
+++ b/config/src/test/resources/org/springframework/security/config/http/RememberMeConfigTests-WithServicesRef.xml
@@ -0,0 +1,47 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/config/src/test/resources/org/springframework/security/config/http/RememberMeConfigTests-WithTokenRepository.xml b/config/src/test/resources/org/springframework/security/config/http/RememberMeConfigTests-WithTokenRepository.xml
new file mode 100644
index 0000000000..009506769c
--- /dev/null
+++ b/config/src/test/resources/org/springframework/security/config/http/RememberMeConfigTests-WithTokenRepository.xml
@@ -0,0 +1,51 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/config/src/test/resources/org/springframework/security/config/http/RememberMeConfigTests-WithUserDetailsService.xml b/config/src/test/resources/org/springframework/security/config/http/RememberMeConfigTests-WithUserDetailsService.xml
new file mode 100644
index 0000000000..8b18a9d966
--- /dev/null
+++ b/config/src/test/resources/org/springframework/security/config/http/RememberMeConfigTests-WithUserDetailsService.xml
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/config/src/test/resources/org/springframework/security/config/http/userservice.xml b/config/src/test/resources/org/springframework/security/config/http/userservice.xml
index e9eeeceb96..62a7b3f6ab 100644
--- a/config/src/test/resources/org/springframework/security/config/http/userservice.xml
+++ b/config/src/test/resources/org/springframework/security/config/http/userservice.xml
@@ -23,7 +23,7 @@
http://www.springframework.org/schema/security/spring-security.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
-
+