From 3608d8aa54cf7bd97424a33804935fced56bfae5 Mon Sep 17 00:00:00 2001 From: Marcus Da Coregio Date: Thu, 26 Oct 2023 14:51:47 -0300 Subject: [PATCH] Log a warning if custom DefaultCookieSerializer does not have rememberMeRequestAttribute set Closes gh-2568 --- .../http/SpringHttpSessionConfiguration.java | 19 ++++++++++-- .../web/http/DefaultCookieSerializer.java | 10 ++++++ .../SpringHttpSessionConfigurationTests.java | 31 +++++++++++++++++++ 3 files changed, 57 insertions(+), 3 deletions(-) diff --git a/spring-session-core/src/main/java/org/springframework/session/config/annotation/web/http/SpringHttpSessionConfiguration.java b/spring-session-core/src/main/java/org/springframework/session/config/annotation/web/http/SpringHttpSessionConfiguration.java index b684ec33..bd952987 100644 --- a/spring-session-core/src/main/java/org/springframework/session/config/annotation/web/http/SpringHttpSessionConfiguration.java +++ b/spring-session-core/src/main/java/org/springframework/session/config/annotation/web/http/SpringHttpSessionConfiguration.java @@ -108,9 +108,7 @@ public class SpringHttpSessionConfiguration implements InitializingBean, Applica @Override public void afterPropertiesSet() { - CookieSerializer cookieSerializer = (this.cookieSerializer != null) ? this.cookieSerializer - : createDefaultCookieSerializer(); - this.defaultHttpSessionIdResolver.setCookieSerializer(cookieSerializer); + this.defaultHttpSessionIdResolver.setCookieSerializer(getCookieSerializer()); } @Bean @@ -154,6 +152,21 @@ public class SpringHttpSessionConfiguration implements InitializingBean, Applica this.httpSessionListeners = listeners; } + private CookieSerializer getCookieSerializer() { + if (this.cookieSerializer != null) { + if (this.cookieSerializer instanceof DefaultCookieSerializer defaultCookieSerializer + && this.usesSpringSessionRememberMeServices + && defaultCookieSerializer.getRememberMeRequestAttribute() == null) { + this.logger.warn("Spring Session Remember Me support is enabled " + + "and the DefaultCookieSerializer is provided explicitly. " + + "The DefaultCookieSerializer must be configured with " + + "setRememberMeRequestAttribute(String) in order to support Remember Me."); + } + return this.cookieSerializer; + } + return createDefaultCookieSerializer(); + } + private CookieSerializer createDefaultCookieSerializer() { DefaultCookieSerializer cookieSerializer = new DefaultCookieSerializer(); if (this.servletContext != null) { diff --git a/spring-session-core/src/main/java/org/springframework/session/web/http/DefaultCookieSerializer.java b/spring-session-core/src/main/java/org/springframework/session/web/http/DefaultCookieSerializer.java index 6c97919c..7b350ac3 100644 --- a/spring-session-core/src/main/java/org/springframework/session/web/http/DefaultCookieSerializer.java +++ b/spring-session-core/src/main/java/org/springframework/session/web/http/DefaultCookieSerializer.java @@ -434,4 +434,14 @@ public class DefaultCookieSerializer implements CookieSerializer { return this.cookiePath; } + /** + * Gets the name of the request attribute that is checked to see if the cookie should + * be written with {@link Integer#MAX_VALUE}. + * @return the remember me request attribute + * @since 3.2 + */ + public String getRememberMeRequestAttribute() { + return this.rememberMeRequestAttribute; + } + } diff --git a/spring-session-core/src/test/java/org/springframework/session/config/annotation/web/http/SpringHttpSessionConfigurationTests.java b/spring-session-core/src/test/java/org/springframework/session/config/annotation/web/http/SpringHttpSessionConfigurationTests.java index c9b8abd1..cb04e055 100644 --- a/spring-session-core/src/test/java/org/springframework/session/config/annotation/web/http/SpringHttpSessionConfigurationTests.java +++ b/spring-session-core/src/test/java/org/springframework/session/config/annotation/web/http/SpringHttpSessionConfigurationTests.java @@ -19,8 +19,11 @@ package org.springframework.session.config.annotation.web.http; import java.util.concurrent.ConcurrentHashMap; import jakarta.servlet.ServletContext; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; +import org.mockito.MockedStatic; import org.springframework.beans.factory.UnsatisfiedDependencyException; import org.springframework.context.annotation.AnnotationConfigApplicationContext; @@ -38,6 +41,10 @@ import org.springframework.test.util.ReflectionTestUtils; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.mockStatic; +import static org.mockito.Mockito.verify; /** * Tests for {@link SpringHttpSessionConfiguration}. @@ -110,6 +117,19 @@ class SpringHttpSessionConfigurationTests { .isEqualTo(SpringSessionRememberMeServices.REMEMBER_ME_LOGIN_ATTR); } + @Test + void rememberMeServicesAndCustomDefaultCookieSerializerThenWarnIfRememberMeRequestAttributeNotSet() { + try (MockedStatic logFactoryMockedStatic = mockStatic(LogFactory.class)) { + Log logMock = mock(); + logFactoryMockedStatic.when(() -> LogFactory.getLog(any(Class.class))).thenReturn(logMock); + registerAndRefresh(RememberMeServicesConfiguration.class, CustomDefaultCookieSerializerConfiguration.class); + verify(logMock).warn("Spring Session Remember Me support is enabled " + + "and the DefaultCookieSerializer is provided explicitly. " + + "The DefaultCookieSerializer must be configured with " + + "setRememberMeRequestAttribute(String) in order to support Remember Me."); + } + } + @Configuration @EnableSpringHttpSession static class EmptyConfiguration { @@ -158,4 +178,15 @@ class SpringHttpSessionConfigurationTests { } + @Configuration + @EnableSpringHttpSession + static class CustomDefaultCookieSerializerConfiguration { + + @Bean + DefaultCookieSerializer defaultCookieSerializer() { + return new DefaultCookieSerializer(); + } + + } + }