diff --git a/config/src/main/java/org/springframework/security/config/annotation/web/configurers/RememberMeConfigurer.java b/config/src/main/java/org/springframework/security/config/annotation/web/configurers/RememberMeConfigurer.java index 0710fc6785..76d7fa0137 100644 --- a/config/src/main/java/org/springframework/security/config/annotation/web/configurers/RememberMeConfigurer.java +++ b/config/src/main/java/org/springframework/security/config/annotation/web/configurers/RememberMeConfigurer.java @@ -79,12 +79,13 @@ import org.springframework.security.web.authentication.ui.DefaultLoginPageGenera */ public final class RememberMeConfigurer> extends AbstractHttpConfigurer, H> { + public static final String REMEMBER_ME = "remember-me"; private AuthenticationSuccessHandler authenticationSuccessHandler; private String key; private RememberMeServices rememberMeServices; private LogoutHandler logoutHandler; - private String rememberMeParameter = "remember-me"; - private String rememberMeCookieName = "remember-me"; + private String rememberMeParameter = REMEMBER_ME; + private String rememberMeCookieName = REMEMBER_ME; private String rememberMeCookieDomain; private PersistentTokenRepository tokenRepository; private UserDetailsService userDetailsService; @@ -244,6 +245,7 @@ public final class RememberMeConfigurer> @SuppressWarnings("unchecked") @Override public void init(H http) throws Exception { + validateInput(); String key = getKey(); RememberMeServices rememberMeServices = getRememberMeServices(http, key); http.setSharedObject(RememberMeServices.class, rememberMeServices); @@ -273,6 +275,17 @@ public final class RememberMeConfigurer> http.addFilter(rememberMeFilter); } + /** + * Validate rememberMeServices and rememberMeCookieName have not been set at + * the same time. + */ + private void validateInput() { + if (this.rememberMeServices != null && this.rememberMeCookieName != REMEMBER_ME) { + throw new IllegalArgumentException("Can not set rememberMeCookieName " + + "and custom rememberMeServices."); + } + } + /** * Returns the HTTP parameter used to indicate to remember the user at time of login. * @return the HTTP parameter used to indicate to remember the user diff --git a/config/src/test/groovy/org/springframework/security/config/annotation/web/configurers/RememberMeConfigurerTests.groovy b/config/src/test/groovy/org/springframework/security/config/annotation/web/configurers/RememberMeConfigurerTests.groovy index abece7399a..2c50d0dd75 100644 --- a/config/src/test/groovy/org/springframework/security/config/annotation/web/configurers/RememberMeConfigurerTests.groovy +++ b/config/src/test/groovy/org/springframework/security/config/annotation/web/configurers/RememberMeConfigurerTests.groovy @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2016 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. @@ -17,24 +17,27 @@ package org.springframework.security.config.annotation.web.configurers import javax.servlet.http.Cookie +import org.springframework.beans.factory.BeanCreationException import org.springframework.beans.factory.annotation.Autowired import org.springframework.mock.web.MockFilterChain import org.springframework.mock.web.MockHttpServletRequest import org.springframework.mock.web.MockHttpServletResponse import org.springframework.mock.web.MockHttpSession import org.springframework.security.authentication.RememberMeAuthenticationToken -import org.springframework.security.authentication.dao.DaoAuthenticationProvider; +import org.springframework.security.authentication.dao.DaoAuthenticationProvider import org.springframework.security.config.annotation.AnyObjectPostProcessor import org.springframework.security.config.annotation.BaseSpringSpec +import org.springframework.security.config.annotation.ObjectPostProcessor import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder import org.springframework.security.config.annotation.web.builders.HttpSecurity import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter -import org.springframework.security.core.authority.AuthorityUtils; +import org.springframework.security.core.authority.AuthorityUtils import org.springframework.security.core.context.SecurityContext -import org.springframework.security.core.userdetails.User; +import org.springframework.security.core.userdetails.User import org.springframework.security.core.userdetails.UserDetailsService -import org.springframework.security.provisioning.InMemoryUserDetailsManager; +import org.springframework.security.provisioning.InMemoryUserDetailsManager +import org.springframework.security.web.authentication.RememberMeServices import org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter import org.springframework.security.web.context.HttpRequestResponseHolder import org.springframework.security.web.context.HttpSessionSecurityContextRepository @@ -43,6 +46,7 @@ import org.springframework.security.web.context.HttpSessionSecurityContextReposi * Tests for RememberMeConfigurer that flex edge cases. {@link NamespaceRememberMeTests} demonstrate mapping of the XML namespace to Java Config. * * @author Rob Winch + * @author EddĂș MelĂ©ndez */ public class RememberMeConfigurerTests extends BaseSpringSpec { @@ -155,7 +159,7 @@ public class RememberMeConfigurerTests extends BaseSpringSpec { response.getRedirectedUrl() == "http://localhost/login" } - def "http/remember-me with cookied domain"() { + def "http/remember-me with cookie domain"() { setup: loadConfig(RememberMeCookieDomainConfig) when: @@ -172,6 +176,29 @@ public class RememberMeConfigurerTests extends BaseSpringSpec { rememberMeCookie.domain == "spring.io" } + def "http/remember-me with cookie name and custom rememberMeServices throws BeanCreationException"() { + setup: + RememberMeCookieDomainCustomRememberMeServicesConfig.REMEMBER_ME = Mock(RememberMeServices) + when: + loadConfig(RememberMeCookieDomainCustomRememberMeServicesConfig) + then: "response contains remember me cookie" + def ex = thrown(BeanCreationException) + ex instanceof BeanCreationException + } + + def "http/remember-me with cookie name and custom rememberMeServices throws IllegalArgumentException"() { + setup: + def httpSec = new HttpSecurity(Mock(ObjectPostProcessor), Mock(AuthenticationManagerBuilder), [:]) + RememberMeConfigurer config = new RememberMeConfigurer(); + config.rememberMeCookieName("COOKIE_NAME") + config.rememberMeServices(Mock(RememberMeServices)) + when: + config.init(httpSec) + then: + IllegalArgumentException ex = thrown() + ex.message == 'Can not set rememberMeCookieName and custom rememberMeServices.' + } + @EnableWebSecurity static class RememberMeConfig extends WebSecurityConfigurerAdapter { protected void configure(HttpSecurity http) throws Exception { @@ -213,6 +240,33 @@ public class RememberMeConfigurerTests extends BaseSpringSpec { } } + @EnableWebSecurity + static class RememberMeCookieDomainCustomRememberMeServicesConfig extends + WebSecurityConfigurerAdapter { + static RememberMeServices REMEMBER_ME + + protected void configure(HttpSecurity http) throws Exception { + http + .authorizeRequests() + .anyRequest().hasRole("USER") + .and() + .formLogin() + .and() + .rememberMe() + .rememberMeCookieName("SPRING_COOKIE_DOMAIN") + .rememberMeCookieDomain("spring.io") + .rememberMeServices(REMEMBER_ME); + } + + @Autowired + public void configureGlobal(AuthenticationManagerBuilder auth) { + auth + .inMemoryAuthentication() + .withUser("user").password("password").roles("USER"); + } + + } + Cookie createRememberMeCookie() { MockHttpServletRequest request = new MockHttpServletRequest() MockHttpServletResponse response = new MockHttpServletResponse()