Add Spring Security's RememberMeServices implementation backed by Spring Session

This commit is contained in:
Vedran Pavic
2016-11-11 14:28:29 +01:00
parent 4c2581d432
commit a2b30eb54b
7 changed files with 574 additions and 4 deletions

View File

@@ -25,7 +25,8 @@ dependencies {
"org.springframework:spring-web:$springVersion",
"org.springframework:spring-messaging:$springVersion",
"org.springframework:spring-websocket:$springVersion",
"org.springframework.security:spring-security-core:$springSecurityVersion"
"org.springframework.security:spring-security-core:$springSecurityVersion",
"org.springframework.security:spring-security-web:$springSecurityVersion"
provided "javax.servlet:javax.servlet-api:$servletApiVersion"
integrationTestCompile "redis.clients:jedis:$jedisVersion",
"org.apache.commons:commons-pool2:2.2",

View File

@@ -19,22 +19,29 @@ package org.springframework.session.config.annotation.web.http;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpSessionListener;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.session.ExpiringSession;
import org.springframework.session.SessionRepository;
import org.springframework.session.events.SessionCreatedEvent;
import org.springframework.session.events.SessionDestroyedEvent;
import org.springframework.session.security.SpringSessionRememberMeServices;
import org.springframework.session.web.http.CookieHttpSessionStrategy;
import org.springframework.session.web.http.CookieSerializer;
import org.springframework.session.web.http.DefaultCookieSerializer;
import org.springframework.session.web.http.HttpSessionStrategy;
import org.springframework.session.web.http.MultiHttpSessionStrategy;
import org.springframework.session.web.http.SessionEventHttpSessionListenerAdapter;
import org.springframework.session.web.http.SessionRepositoryFilter;
import org.springframework.util.ClassUtils;
/**
* Configures the basics for setting up Spring Session in a web environment. In order to
@@ -75,20 +82,38 @@ import org.springframework.session.web.http.SessionRepositoryFilter;
* </ul>
*
* @author Rob Winch
* @author Vedran Pavic
* @since 1.1
*
* @see EnableSpringHttpSession
*/
@Configuration
public class SpringHttpSessionConfiguration {
public class SpringHttpSessionConfiguration implements ApplicationContextAware {
private CookieHttpSessionStrategy defaultHttpSessionStrategy = new CookieHttpSessionStrategy();
private boolean usesSpringSessionRememberMeServices;
private ServletContext servletContext;
private CookieSerializer cookieSerializer;
private HttpSessionStrategy httpSessionStrategy = this.defaultHttpSessionStrategy;
private List<HttpSessionListener> httpSessionListeners = new ArrayList<HttpSessionListener>();
private ServletContext servletContext;
@PostConstruct
public void init() {
if (this.cookieSerializer != null) {
this.defaultHttpSessionStrategy.setCookieSerializer(this.cookieSerializer);
}
else if (this.usesSpringSessionRememberMeServices) {
DefaultCookieSerializer cookieSerializer = new DefaultCookieSerializer();
cookieSerializer.setRememberMeRequestAttribute(
SpringSessionRememberMeServices.REMEMBER_ME_LOGIN_ATTR);
this.defaultHttpSessionStrategy.setCookieSerializer(cookieSerializer);
}
}
@Bean
public SessionEventHttpSessionListenerAdapter sessionEventHttpSessionListenerAdapter() {
@@ -111,6 +136,15 @@ public class SpringHttpSessionConfiguration {
return sessionRepositoryFilter;
}
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
if (ClassUtils.isPresent("org.springframework.security.web.authentication." +
"RememberMeServices", null)) {
this.usesSpringSessionRememberMeServices = !applicationContext
.getBeansOfType(SpringSessionRememberMeServices.class).isEmpty();
}
}
@Autowired(required = false)
public void setServletContext(ServletContext servletContext) {
this.servletContext = servletContext;
@@ -118,7 +152,7 @@ public class SpringHttpSessionConfiguration {
@Autowired(required = false)
public void setCookieSerializer(CookieSerializer cookieSerializer) {
this.defaultHttpSessionStrategy.setCookieSerializer(cookieSerializer);
this.cookieSerializer = cookieSerializer;
}
@Autowired(required = false)
@@ -130,4 +164,5 @@ public class SpringHttpSessionConfiguration {
public void setHttpSessionListeners(List<HttpSessionListener> listeners) {
this.httpSessionListeners = listeners;
}
}

View File

@@ -0,0 +1,124 @@
/*
* Copyright 2014-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.
* 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.session.security;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.RememberMeServices;
import org.springframework.util.Assert;
/**
* A {@link RememberMeServices} implementation that uses Spring Session backed
* {@link HttpSession} to provide remember-me service capabilities.
*
* @author Vedran Pavic
* @since 1.3.0
*/
public class SpringSessionRememberMeServices implements RememberMeServices {
/**
* Remember-me login request attribute name.
*/
public static final String REMEMBER_ME_LOGIN_ATTR = SpringSessionRememberMeServices.class
.getName() + "REMEMBER_ME_LOGIN_ATTR";
private static final String DEFAULT_PARAMETER = "remember-me";
private static final int THIRTY_DAYS_SECONDS = 2592000;
private static final Log logger = LogFactory.getLog(SpringSessionRememberMeServices.class);
private String parameter = DEFAULT_PARAMETER;
private boolean alwaysRemember;
private int validitySeconds = THIRTY_DAYS_SECONDS;
public final Authentication autoLogin(HttpServletRequest request,
HttpServletResponse response) {
return null;
}
public final void loginFail(HttpServletRequest request, HttpServletResponse response) {
logger.debug("Interactive login attempt was unsuccessful.");
HttpSession session = request.getSession(false);
if (session != null) {
session.invalidate();
}
}
public final void loginSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication successfulAuthentication) {
if (!this.alwaysRemember && !rememberMeRequested(request, this.parameter)) {
logger.debug("Remember-me login not requested.");
return;
}
request.setAttribute(REMEMBER_ME_LOGIN_ATTR, true);
request.getSession().setMaxInactiveInterval(this.validitySeconds);
}
/**
* Allows customization of whether a remember-me login has been requested. The default
* is to return {@code true} if the configured parameter name has been included in the
* request and is set to the value {@code true}.
* @param request the request submitted from an interactive login, which may include
* additional information indicating that a persistent login is desired.
* @param parameter the configured remember-me parameter name.
* @return true if the request includes information indicating that a persistent login
* has been requested.
*/
protected boolean rememberMeRequested(HttpServletRequest request, String parameter) {
String rememberMe = request.getParameter(parameter);
if (rememberMe != null) {
if (rememberMe.equalsIgnoreCase("true") || rememberMe.equalsIgnoreCase("on")
|| rememberMe.equalsIgnoreCase("yes") || rememberMe.equals("1")) {
return true;
}
}
if (logger.isDebugEnabled()) {
logger.debug("Did not send remember-me cookie (principal did not set " +
"parameter '" + parameter + "')");
}
return false;
}
/**
* Set the name of the parameter which should be checked for to see if a remember-me
* has been requested during a login request. This should be the same name you assign
* to the checkbox in your login form.
* @param parameter the request parameter
*/
public void setParameter(String parameter) {
Assert.hasText(parameter, "Parameter name cannot be empty or null");
this.parameter = parameter;
}
public void setAlwaysRemember(boolean alwaysRemember) {
this.alwaysRemember = alwaysRemember;
}
public void setValiditySeconds(int validitySeconds) {
this.validitySeconds = validitySeconds;
}
}

View File

@@ -53,6 +53,10 @@ public class DefaultCookieSerializer implements CookieSerializer {
private boolean useBase64Encoding;
private String rememberMeRequestAttribute;
private int rememberMeCookieMaxAge = Integer.MAX_VALUE;
/*
* (non-Javadoc)
*
@@ -111,6 +115,10 @@ public class DefaultCookieSerializer implements CookieSerializer {
if ("".equals(requestedCookieValue)) {
sessionCookie.setMaxAge(0);
}
else if (this.rememberMeRequestAttribute != null &&
request.getAttribute(this.rememberMeRequestAttribute) != null) {
sessionCookie.setMaxAge(this.rememberMeCookieMaxAge);
}
else {
sessionCookie.setMaxAge(this.cookieMaxAge);
}
@@ -201,6 +209,10 @@ public class DefaultCookieSerializer implements CookieSerializer {
* @param cookieMaxAge the maxAge property of the Cookie
*/
public void setCookieMaxAge(int cookieMaxAge) {
if (cookieMaxAge > this.rememberMeCookieMaxAge) {
throw new IllegalArgumentException("cookieMaxAge cannot be greater than " +
"rememberMeCookieMaxAge");
}
this.cookieMaxAge = cookieMaxAge;
}
@@ -291,6 +303,36 @@ public class DefaultCookieSerializer implements CookieSerializer {
this.useBase64Encoding = useBase64Encoding;
}
/**
* Set the request attribute name that indicates remember-me login. Used to write
* {@link Cookie} with {@code maxAge} property indicated by
* {@link #rememberMeCookieMaxAge}.
* @param rememberMeRequestAttribute the remember-me request attribute name
* @since 1.3.0
* @see #setRememberMeCookieMaxAge(int)
*/
public void setRememberMeRequestAttribute(String rememberMeRequestAttribute) {
if (rememberMeRequestAttribute == null) {
throw new IllegalArgumentException(
"rememberMeRequestAttribute cannot be null");
}
this.rememberMeRequestAttribute = rememberMeRequestAttribute;
}
/**
* Set the {@code maxAge} property of the {@link Cookie} to be used when remember-me
* is requested. The default is {@link Integer#MAX_VALUE}.
* @param rememberMeCookieMaxAge the {@code maxAge} property of the {@code Cookie}
* @since 1.3.0
*/
public void setRememberMeCookieMaxAge(int rememberMeCookieMaxAge) {
if (rememberMeCookieMaxAge < 1 || rememberMeCookieMaxAge < this.cookieMaxAge) {
throw new IllegalArgumentException("rememberMeCookieMaxAge must be greater " +
"than zero and greater than cookieMaxAge");
}
this.rememberMeCookieMaxAge = rememberMeCookieMaxAge;
}
private String getDomainName(HttpServletRequest request) {
if (this.domainName != null) {
return this.domainName;

View File

@@ -0,0 +1,135 @@
/*
* Copyright 2014-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.
* 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.session.config.annotation.web.http;
import org.junit.After;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
import org.mockito.runners.MockitoJUnitRunner;
import org.springframework.beans.factory.UnsatisfiedDependencyException;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.session.MapSessionRepository;
import org.springframework.session.SessionRepository;
import org.springframework.session.security.SpringSessionRememberMeServices;
import org.springframework.session.web.http.CookieHttpSessionStrategy;
import org.springframework.session.web.http.DefaultCookieSerializer;
import org.springframework.session.web.http.SessionEventHttpSessionListenerAdapter;
import org.springframework.session.web.http.SessionRepositoryFilter;
import org.springframework.test.util.ReflectionTestUtils;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link SpringHttpSessionConfiguration}.
*
* @author Vedran Pavic
*/
@RunWith(MockitoJUnitRunner.class)
public class SpringHttpSessionConfigurationTests {
@Rule
public final ExpectedException thrown = ExpectedException.none();
private AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
@After
public void closeContext() {
if (this.context != null) {
this.context.close();
}
}
private void registerAndRefresh(Class<?>... annotatedClasses) {
this.context.register(annotatedClasses);
this.context.refresh();
}
@Test
public void noSessionRepositoryConfiguration() {
this.thrown.expect(UnsatisfiedDependencyException.class);
this.thrown.expectMessage("org.springframework.session.SessionRepository");
registerAndRefresh(EmptyConfiguration.class);
}
@Test
public void defaultConfiguration() {
registerAndRefresh(DefaultConfiguration.class);
assertThat(this.context.getBean(SessionEventHttpSessionListenerAdapter.class))
.isNotNull();
assertThat(this.context.getBean(SessionRepositoryFilter.class)).isNotNull();
assertThat(this.context.getBean(SessionRepository.class)).isNotNull();
}
@Test
public void rememberMeServicesConfiguration() {
registerAndRefresh(RememberMeServicesConfiguration.class);
SessionRepositoryFilter sessionRepositoryFilter = this.context.getBean(
SessionRepositoryFilter.class);
assertThat(sessionRepositoryFilter).isNotNull();
CookieHttpSessionStrategy httpSessionStrategy =
(CookieHttpSessionStrategy) ReflectionTestUtils.getField(
sessionRepositoryFilter, "httpSessionStrategy");
assertThat(httpSessionStrategy).isNotNull();
DefaultCookieSerializer cookieSerializer =
(DefaultCookieSerializer) ReflectionTestUtils.getField(
httpSessionStrategy, "cookieSerializer");
assertThat(cookieSerializer).isNotNull();
assertThat(ReflectionTestUtils.getField(
cookieSerializer, "rememberMeRequestAttribute"))
.isEqualTo(SpringSessionRememberMeServices.REMEMBER_ME_LOGIN_ATTR);
}
@Configuration
@EnableSpringHttpSession
static class EmptyConfiguration {
}
static class BaseConfiguration {
@Bean
public MapSessionRepository sessionRepository() {
return new MapSessionRepository();
}
}
@Configuration
@EnableSpringHttpSession
static class DefaultConfiguration extends BaseConfiguration {
}
@Configuration
@EnableSpringHttpSession
static class RememberMeServicesConfiguration extends BaseConfiguration {
@Bean
public SpringSessionRememberMeServices rememberMeServices() {
return new SpringSessionRememberMeServices();
}
}
}

View File

@@ -0,0 +1,189 @@
/*
* Copyright 2014-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.
* 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.session.security;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.springframework.security.core.Authentication;
import org.springframework.test.util.ReflectionTestUtils;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.BDDMockito.given;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
/**
* Tests for {@link SpringSessionRememberMeServices}.
*
* @author Vedran Pavic
*/
public class SpringSessionRememberMeServicesTests {
@Rule
public ExpectedException thrown = ExpectedException.none();
private SpringSessionRememberMeServices rememberMeServices;
@Test
public void create() {
this.rememberMeServices = new SpringSessionRememberMeServices();
assertThat(ReflectionTestUtils.getField(this.rememberMeServices, "parameter"))
.isEqualTo("remember-me");
assertThat(ReflectionTestUtils.getField(this.rememberMeServices, "alwaysRemember"))
.isEqualTo(false);
assertThat(ReflectionTestUtils.getField(this.rememberMeServices, "validitySeconds"))
.isEqualTo(2592000);
}
@Test
public void createWithCustomParameter() {
this.rememberMeServices = new SpringSessionRememberMeServices();
this.rememberMeServices.setParameter("test-param");
assertThat(ReflectionTestUtils.getField(this.rememberMeServices, "parameter"))
.isEqualTo("test-param");
}
@Test
public void createWithNullParameter() {
this.thrown.expect(IllegalArgumentException.class);
this.thrown.expectMessage("Parameter name cannot be empty or null");
this.rememberMeServices = new SpringSessionRememberMeServices();
this.rememberMeServices.setParameter(null);
}
@Test
public void createWithAlwaysRemember() {
this.rememberMeServices = new SpringSessionRememberMeServices();
this.rememberMeServices.setAlwaysRemember(true);
assertThat(ReflectionTestUtils.getField(this.rememberMeServices, "alwaysRemember"))
.isEqualTo(true);
}
@Test
public void createWithCustomValidity() {
this.rememberMeServices = new SpringSessionRememberMeServices();
this.rememberMeServices.setValiditySeconds(100000);
assertThat(ReflectionTestUtils.getField(this.rememberMeServices, "validitySeconds"))
.isEqualTo(100000);
}
@Test
public void autoLogin() {
HttpServletRequest request = mock(HttpServletRequest.class);
HttpServletResponse response = mock(HttpServletResponse.class);
this.rememberMeServices = new SpringSessionRememberMeServices();
this.rememberMeServices.autoLogin(request, response);
verifyZeroInteractions(request, response);
}
@Test
public void loginFailInvalidatesSession() {
HttpServletRequest request = mock(HttpServletRequest.class);
HttpServletResponse response = mock(HttpServletResponse.class);
HttpSession session = mock(HttpSession.class);
given(request.getSession(eq(false))).willReturn(session);
this.rememberMeServices = new SpringSessionRememberMeServices();
this.rememberMeServices.loginFail(request, response);
verify(request, times(1)).getSession(eq(false));
verify(session, times(1)).invalidate();
verifyZeroInteractions(request, response, session);
}
@Test
public void loginSuccess() {
HttpServletRequest request = mock(HttpServletRequest.class);
HttpServletResponse response = mock(HttpServletResponse.class);
Authentication authentication = mock(Authentication.class);
HttpSession session = mock(HttpSession.class);
given(request.getParameter(eq("remember-me"))).willReturn("true");
given(request.getSession()).willReturn(session);
this.rememberMeServices = new SpringSessionRememberMeServices();
this.rememberMeServices.loginSuccess(request, response, authentication);
verify(request, times(1)).getParameter(eq("remember-me"));
verify(request, times(1)).getSession();
verify(request, times(1)).setAttribute(
eq(SpringSessionRememberMeServices.REMEMBER_ME_LOGIN_ATTR), eq(true));
verify(session, times(1)).setMaxInactiveInterval(eq(2592000));
verifyZeroInteractions(request, response, session, authentication);
}
@Test
public void loginSuccessWithCustomParameter() {
HttpServletRequest request = mock(HttpServletRequest.class);
HttpServletResponse response = mock(HttpServletResponse.class);
Authentication authentication = mock(Authentication.class);
HttpSession session = mock(HttpSession.class);
given(request.getParameter(eq("test-param"))).willReturn("true");
given(request.getSession()).willReturn(session);
this.rememberMeServices = new SpringSessionRememberMeServices();
this.rememberMeServices.setParameter("test-param");
this.rememberMeServices.loginSuccess(request, response, authentication);
verify(request, times(1)).getParameter(eq("test-param"));
verify(request, times(1)).getSession();
verify(request, times(1)).setAttribute(
eq(SpringSessionRememberMeServices.REMEMBER_ME_LOGIN_ATTR), eq(true));
verify(session, times(1)).setMaxInactiveInterval(eq(2592000));
verifyZeroInteractions(request, response, session, authentication);
}
@Test
public void loginSuccessWithAlwaysRemember() {
HttpServletRequest request = mock(HttpServletRequest.class);
HttpServletResponse response = mock(HttpServletResponse.class);
Authentication authentication = mock(Authentication.class);
HttpSession session = mock(HttpSession.class);
given(request.getSession()).willReturn(session);
this.rememberMeServices = new SpringSessionRememberMeServices();
this.rememberMeServices.setAlwaysRemember(true);
this.rememberMeServices.loginSuccess(request, response, authentication);
verify(request, times(1)).getSession();
verify(request, times(1)).setAttribute(
eq(SpringSessionRememberMeServices.REMEMBER_ME_LOGIN_ATTR), eq(true));
verify(session, times(1)).setMaxInactiveInterval(eq(2592000));
verifyZeroInteractions(request, response, session, authentication);
}
@Test
public void loginSuccessWithCustomValidity() {
HttpServletRequest request = mock(HttpServletRequest.class);
HttpServletResponse response = mock(HttpServletResponse.class);
Authentication authentication = mock(Authentication.class);
HttpSession session = mock(HttpSession.class);
given(request.getParameter(eq("remember-me")))
.willReturn("true");
given(request.getSession()).willReturn(session);
this.rememberMeServices = new SpringSessionRememberMeServices();
this.rememberMeServices.setValiditySeconds(100000);
this.rememberMeServices.loginSuccess(request, response, authentication);
verify(request, times(1)).getParameter(eq("remember-me"));
verify(request, times(1)).getSession();
verify(request, times(1)).setAttribute(
eq(SpringSessionRememberMeServices.REMEMBER_ME_LOGIN_ATTR), eq(true));
verify(session, times(1)).setMaxInactiveInterval(eq(100000));
verifyZeroInteractions(request, response, session, authentication);
}
}

View File

@@ -19,7 +19,9 @@ package org.springframework.session.web.http;
import javax.servlet.http.Cookie;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
@@ -45,6 +47,9 @@ public class DefaultCookieSerializerTests {
return new Object[] { false, true };
}
@Rule
public ExpectedException thrown = ExpectedException.none();
private boolean useBase64Encoding;
private String cookieName;
@@ -424,6 +429,45 @@ public class DefaultCookieSerializerTests {
assertThat(this.serializer.readCookieValues(this.request)).containsOnly("");
}
// --- rememberMe ---
@Test
public void setRememberMeCookieMaxAgeNotGreaterThanZero() {
this.thrown.expect(IllegalArgumentException.class);
this.thrown.expectMessage("rememberMeCookieMaxAge must be greater than zero and " +
"greater than cookieMaxAge");
this.serializer.setRememberMeCookieMaxAge(0);
}
@Test
public void setRememberMeCookieMaxAgeNotGreaterMaxCookieAge() {
this.thrown.expect(IllegalArgumentException.class);
this.thrown.expectMessage("rememberMeCookieMaxAge must be greater than zero and " +
"greater than cookieMaxAge");
this.serializer.setCookieMaxAge(20);
this.serializer.setRememberMeCookieMaxAge(10);
}
@Test
public void writeCookieRememberMeCookieMaxAgeDefault() {
this.request.setAttribute("rememberMe", true);
this.serializer.setRememberMeRequestAttribute("rememberMe");
this.serializer.writeCookieValue(cookieValue(this.sessionId));
assertThat(getCookie().getMaxAge()).isEqualTo(Integer.MAX_VALUE);
}
@Test
public void writeCookieRememberMeCookieMaxAgeExplicit() {
this.request.setAttribute("rememberMe", true);
this.serializer.setRememberMeRequestAttribute("rememberMe");
this.serializer.setRememberMeCookieMaxAge(100);
this.serializer.writeCookieValue(cookieValue(this.sessionId));
assertThat(getCookie().getMaxAge()).isEqualTo(100);
}
public void setCookieName(String cookieName) {
this.cookieName = cookieName;
this.serializer.setCookieName(cookieName);