parent
ce20cfcb98
commit
41c6a797c3
|
@ -74,6 +74,7 @@ import org.springframework.security.web.authentication.ui.DefaultLoginPageGenera
|
||||||
* </ul>
|
* </ul>
|
||||||
*
|
*
|
||||||
* @author Rob Winch
|
* @author Rob Winch
|
||||||
|
* @author Eddú Meléndez
|
||||||
* @since 3.2
|
* @since 3.2
|
||||||
*/
|
*/
|
||||||
public final class RememberMeConfigurer<H extends HttpSecurityBuilder<H>> extends
|
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 LogoutHandler logoutHandler;
|
||||||
private String rememberMeParameter = "remember-me";
|
private String rememberMeParameter = "remember-me";
|
||||||
private String rememberMeCookieName = "remember-me";
|
private String rememberMeCookieName = "remember-me";
|
||||||
|
private String rememberMeCookieDomain;
|
||||||
private PersistentTokenRepository tokenRepository;
|
private PersistentTokenRepository tokenRepository;
|
||||||
private UserDetailsService userDetailsService;
|
private UserDetailsService userDetailsService;
|
||||||
private Integer tokenValiditySeconds;
|
private Integer tokenValiditySeconds;
|
||||||
|
@ -192,6 +194,18 @@ public final class RememberMeConfigurer<H extends HttpSecurityBuilder<H>> extend
|
||||||
return this;
|
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
|
* 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
|
* 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);
|
http, key);
|
||||||
tokenRememberMeServices.setParameter(rememberMeParameter);
|
tokenRememberMeServices.setParameter(rememberMeParameter);
|
||||||
tokenRememberMeServices.setCookieName(rememberMeCookieName);
|
tokenRememberMeServices.setCookieName(rememberMeCookieName);
|
||||||
|
if (rememberMeCookieDomain != null) {
|
||||||
|
tokenRememberMeServices.setCookieDomain(rememberMeCookieDomain);
|
||||||
|
}
|
||||||
if (tokenValiditySeconds != null) {
|
if (tokenValiditySeconds != null) {
|
||||||
tokenRememberMeServices.setTokenValiditySeconds(tokenValiditySeconds);
|
tokenRememberMeServices.setTokenValiditySeconds(tokenValiditySeconds);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,6 @@ package org.springframework.security.config.annotation.web.configurers
|
||||||
import javax.servlet.http.Cookie
|
import javax.servlet.http.Cookie
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired
|
import org.springframework.beans.factory.annotation.Autowired
|
||||||
import org.springframework.context.annotation.Configuration
|
|
||||||
import org.springframework.mock.web.MockFilterChain
|
import org.springframework.mock.web.MockFilterChain
|
||||||
import org.springframework.mock.web.MockHttpServletRequest
|
import org.springframework.mock.web.MockHttpServletRequest
|
||||||
import org.springframework.mock.web.MockHttpServletResponse
|
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.AnyObjectPostProcessor
|
||||||
import org.springframework.security.config.annotation.BaseSpringSpec
|
import org.springframework.security.config.annotation.BaseSpringSpec
|
||||||
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder
|
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.builders.HttpSecurity
|
||||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity
|
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity
|
||||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter
|
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter
|
||||||
|
@ -157,6 +155,23 @@ public class RememberMeConfigurerTests extends BaseSpringSpec {
|
||||||
response.getRedirectedUrl() == "http://localhost/login"
|
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
|
@EnableWebSecurity
|
||||||
static class RememberMeConfig extends WebSecurityConfigurerAdapter {
|
static class RememberMeConfig extends WebSecurityConfigurerAdapter {
|
||||||
protected void configure(HttpSecurity http) throws Exception {
|
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() {
|
Cookie createRememberMeCookie() {
|
||||||
MockHttpServletRequest request = new MockHttpServletRequest()
|
MockHttpServletRequest request = new MockHttpServletRequest()
|
||||||
MockHttpServletResponse response = new MockHttpServletResponse()
|
MockHttpServletResponse response = new MockHttpServletResponse()
|
||||||
|
|
|
@ -50,6 +50,7 @@ import org.springframework.util.StringUtils;
|
||||||
*
|
*
|
||||||
* @author Luke Taylor
|
* @author Luke Taylor
|
||||||
* @author Rob Winch
|
* @author Rob Winch
|
||||||
|
* @author Eddú Meléndez
|
||||||
* @since 2.0
|
* @since 2.0
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractRememberMeServices implements RememberMeServices,
|
public abstract class AbstractRememberMeServices implements RememberMeServices,
|
||||||
|
@ -75,6 +76,7 @@ public abstract class AbstractRememberMeServices implements RememberMeServices,
|
||||||
private AuthenticationDetailsSource<HttpServletRequest, ?> authenticationDetailsSource = new WebAuthenticationDetailsSource();
|
private AuthenticationDetailsSource<HttpServletRequest, ?> authenticationDetailsSource = new WebAuthenticationDetailsSource();
|
||||||
|
|
||||||
private String cookieName = SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY;
|
private String cookieName = SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY;
|
||||||
|
private String cookieDomain;
|
||||||
private String parameter = DEFAULT_PARAMETER;
|
private String parameter = DEFAULT_PARAMETER;
|
||||||
private boolean alwaysRemember;
|
private boolean alwaysRemember;
|
||||||
private String key;
|
private String key;
|
||||||
|
@ -385,7 +387,9 @@ public abstract class AbstractRememberMeServices implements RememberMeServices,
|
||||||
Cookie cookie = new Cookie(cookieName, cookieValue);
|
Cookie cookie = new Cookie(cookieName, cookieValue);
|
||||||
cookie.setMaxAge(maxAge);
|
cookie.setMaxAge(maxAge);
|
||||||
cookie.setPath(getCookiePath(request));
|
cookie.setPath(getCookiePath(request));
|
||||||
|
if (cookieDomain != null) {
|
||||||
|
cookie.setDomain(cookieDomain);
|
||||||
|
}
|
||||||
if (maxAge < 1) {
|
if (maxAge < 1) {
|
||||||
cookie.setVersion(1);
|
cookie.setVersion(1);
|
||||||
}
|
}
|
||||||
|
@ -430,6 +434,11 @@ public abstract class AbstractRememberMeServices implements RememberMeServices,
|
||||||
this.cookieName = cookieName;
|
this.cookieName = cookieName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setCookieDomain(String cookieDomain) {
|
||||||
|
Assert.hasLength(cookieDomain, "Cookie domain cannot be empty or null");
|
||||||
|
this.cookieDomain = cookieDomain;
|
||||||
|
}
|
||||||
|
|
||||||
protected String getCookieName() {
|
protected String getCookieName() {
|
||||||
return cookieName;
|
return cookieName;
|
||||||
}
|
}
|
||||||
|
|
|
@ -420,6 +420,21 @@ public class AbstractRememberMeServicesTests {
|
||||||
assertThat(cookie.getVersion()).isEqualTo(0);
|
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) {
|
private Cookie[] createLoginCookie(String cookieToken) {
|
||||||
MockRememberMeServices services = new MockRememberMeServices(uds);
|
MockRememberMeServices services = new MockRememberMeServices(uds);
|
||||||
Cookie cookie = new Cookie(
|
Cookie cookie = new Cookie(
|
||||||
|
|
Loading…
Reference in New Issue