瀏覽代碼

Add RememberMeConfigurer set domain

Fixes gh-3408
Eddú Meléndez 9 年之前
父節點
當前提交
41c6a797c3

+ 17 - 0
config/src/main/java/org/springframework/security/config/annotation/web/configurers/RememberMeConfigurer.java

@@ -74,6 +74,7 @@ import org.springframework.security.web.authentication.ui.DefaultLoginPageGenera
  * </ul>
  *
  * @author Rob Winch
+ * @author Eddú Meléndez
  * @since 3.2
  */
 public final class RememberMeConfigurer<H extends HttpSecurityBuilder<H>> extends
@@ -84,6 +85,7 @@ public final class RememberMeConfigurer<H extends HttpSecurityBuilder<H>> extend
 	private LogoutHandler logoutHandler;
 	private String rememberMeParameter = "remember-me";
 	private String rememberMeCookieName = "remember-me";
+	private String rememberMeCookieDomain;
 	private PersistentTokenRepository tokenRepository;
 	private UserDetailsService userDetailsService;
 	private Integer tokenValiditySeconds;
@@ -192,6 +194,18 @@ public final class RememberMeConfigurer<H extends HttpSecurityBuilder<H>> extend
 		return this;
 	}
 
+	/**
+	 * The domain name within which the remember me cookie is visible.
+	 *
+	 * @param rememberMeCookieDomain the domain name within which the remember me cookie is visible.
+	 * @return the {@link RememberMeConfigurer} for further customization
+	 * @since 4.1.0
+	 */
+	public RememberMeConfigurer<H> rememberMeCookieDomain(String rememberMeCookieDomain) {
+		this.rememberMeCookieDomain = rememberMeCookieDomain;
+		return this;
+	}
+
 	/**
 	 * Allows control over the destination a remembered user is sent to when they are
 	 * successfully authenticated. By default, the filter will just allow the current
@@ -294,6 +308,9 @@ public final class RememberMeConfigurer<H extends HttpSecurityBuilder<H>> extend
 				http, key);
 		tokenRememberMeServices.setParameter(rememberMeParameter);
 		tokenRememberMeServices.setCookieName(rememberMeCookieName);
+		if (rememberMeCookieDomain != null) {
+			tokenRememberMeServices.setCookieDomain(rememberMeCookieDomain);
+		}
 		if (tokenValiditySeconds != null) {
 			tokenRememberMeServices.setTokenValiditySeconds(tokenValiditySeconds);
 		}

+ 38 - 2
config/src/test/groovy/org/springframework/security/config/annotation/web/configurers/RememberMeConfigurerTests.groovy

@@ -18,7 +18,6 @@ package org.springframework.security.config.annotation.web.configurers
 import javax.servlet.http.Cookie
 
 import org.springframework.beans.factory.annotation.Autowired
-import org.springframework.context.annotation.Configuration
 import org.springframework.mock.web.MockFilterChain
 import org.springframework.mock.web.MockHttpServletRequest
 import org.springframework.mock.web.MockHttpServletResponse
@@ -28,7 +27,6 @@ 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.authentication.builders.AuthenticationManagerBuilder
-import org.springframework.security.config.annotation.authentication.configurers.provisioning.InMemoryUserDetailsManagerConfigurer;
 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
@@ -157,6 +155,23 @@ public class RememberMeConfigurerTests extends BaseSpringSpec {
 			response.getRedirectedUrl() == "http://localhost/login"
 	}
 
+	def "http/remember-me with cookied domain"() {
+		setup:
+			loadConfig(RememberMeCookieDomainConfig)
+		when:
+			super.setup()
+			request.servletPath = "/login"
+			request.method = "POST"
+			request.parameters.username = ["user"] as String[]
+			request.parameters.password = ["password"] as String[]
+			request.parameters.'remember-me' = ["true"] as String[]
+			springSecurityFilterChain.doFilter(request,response,chain)
+			Cookie rememberMeCookie = getRememberMeCookie()
+		then: "response contains remember me cookie"
+			rememberMeCookie != null
+			rememberMeCookie.domain == "spring.io"
+	}
+
 	@EnableWebSecurity
 	static class RememberMeConfig extends WebSecurityConfigurerAdapter {
 		protected void configure(HttpSecurity http) throws Exception {
@@ -177,6 +192,27 @@ public class RememberMeConfigurerTests extends BaseSpringSpec {
 		}
 	}
 
+	@EnableWebSecurity
+	static class RememberMeCookieDomainConfig extends WebSecurityConfigurerAdapter {
+		protected void configure(HttpSecurity http) throws Exception {
+			http
+					.authorizeRequests()
+					.anyRequest().hasRole("USER")
+					.and()
+					.formLogin()
+					.and()
+					.rememberMe()
+					.rememberMeCookieDomain("spring.io")
+		}
+
+		@Autowired
+		public void configureGlobal(AuthenticationManagerBuilder auth) {
+			auth
+					.inMemoryAuthentication()
+					.withUser("user").password("password").roles("USER");
+		}
+	}
+
 	Cookie createRememberMeCookie() {
 		MockHttpServletRequest request = new MockHttpServletRequest()
 		MockHttpServletResponse response = new MockHttpServletResponse()

+ 10 - 1
web/src/main/java/org/springframework/security/web/authentication/rememberme/AbstractRememberMeServices.java

@@ -50,6 +50,7 @@ import org.springframework.util.StringUtils;
  *
  * @author Luke Taylor
  * @author Rob Winch
+ * @author Eddú Meléndez
  * @since 2.0
  */
 public abstract class AbstractRememberMeServices implements RememberMeServices,
@@ -75,6 +76,7 @@ public abstract class AbstractRememberMeServices implements RememberMeServices,
 	private AuthenticationDetailsSource<HttpServletRequest, ?> authenticationDetailsSource = new WebAuthenticationDetailsSource();
 
 	private String cookieName = SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY;
+	private String cookieDomain;
 	private String parameter = DEFAULT_PARAMETER;
 	private boolean alwaysRemember;
 	private String key;
@@ -385,7 +387,9 @@ public abstract class AbstractRememberMeServices implements RememberMeServices,
 		Cookie cookie = new Cookie(cookieName, cookieValue);
 		cookie.setMaxAge(maxAge);
 		cookie.setPath(getCookiePath(request));
-
+		if (cookieDomain != null) {
+			cookie.setDomain(cookieDomain);
+		}
 		if (maxAge < 1) {
 			cookie.setVersion(1);
 		}
@@ -430,6 +434,11 @@ public abstract class AbstractRememberMeServices implements RememberMeServices,
 		this.cookieName = cookieName;
 	}
 
+	public void setCookieDomain(String cookieDomain) {
+		Assert.hasLength(cookieDomain, "Cookie domain cannot be empty or null");
+		this.cookieDomain = cookieDomain;
+	}
+
 	protected String getCookieName() {
 		return cookieName;
 	}

+ 15 - 0
web/src/test/java/org/springframework/security/web/authentication/rememberme/AbstractRememberMeServicesTests.java

@@ -420,6 +420,21 @@ public class AbstractRememberMeServicesTests {
 		assertThat(cookie.getVersion()).isEqualTo(0);
 	}
 
+	@Test
+	public void setCookieDomainValue() {
+		MockRememberMeServices services = new MockRememberMeServices();
+		MockHttpServletRequest request = new MockHttpServletRequest();
+		MockHttpServletResponse response = new MockHttpServletResponse();
+
+		services.setCookieName("mycookiename");
+		services.setCookieDomain("spring.io");
+		services.setCookie(new String[] { "mycookie" }, 1000, request, response);
+		Cookie cookie = response.getCookie("mycookiename");
+
+		assertThat(cookie).isNotNull();
+		assertThat(cookie.getDomain()).isEqualTo("spring.io");
+	}
+
 	private Cookie[] createLoginCookie(String cookieToken) {
 		MockRememberMeServices services = new MockRememberMeServices(uds);
 		Cookie cookie = new Cookie(