Skip to content

Commit a4899a9

Browse files
committed
Auto-configure Spring Session's cookie serializer
1 parent 90bfd0b commit a4899a9

File tree

2 files changed

+127
-1
lines changed

2 files changed

+127
-1
lines changed

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/SessionAutoConfiguration.java

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,16 +39,23 @@
3939
import org.springframework.boot.autoconfigure.hazelcast.HazelcastAutoConfiguration;
4040
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
4141
import org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration;
42+
import org.springframework.boot.autoconfigure.web.ServerProperties;
4243
import org.springframework.boot.autoconfigure.web.reactive.HttpHandlerAutoConfiguration;
4344
import org.springframework.boot.context.properties.EnableConfigurationProperties;
45+
import org.springframework.boot.context.properties.PropertyMapper;
46+
import org.springframework.boot.web.servlet.server.Session.Cookie;
4447
import org.springframework.context.ApplicationContext;
48+
import org.springframework.context.annotation.Bean;
4549
import org.springframework.context.annotation.Configuration;
4650
import org.springframework.context.annotation.Import;
4751
import org.springframework.context.annotation.ImportSelector;
4852
import org.springframework.core.type.AnnotationMetadata;
4953
import org.springframework.session.ReactiveSessionRepository;
5054
import org.springframework.session.Session;
5155
import org.springframework.session.SessionRepository;
56+
import org.springframework.session.web.http.CookieSerializer;
57+
import org.springframework.session.web.http.DefaultCookieSerializer;
58+
import org.springframework.session.web.http.HeaderHttpSessionIdResolver;
5259
import org.springframework.util.StringUtils;
5360

5461
/**
@@ -64,7 +71,7 @@
6471
@Configuration
6572
@ConditionalOnClass(Session.class)
6673
@ConditionalOnWebApplication
67-
@EnableConfigurationProperties(SessionProperties.class)
74+
@EnableConfigurationProperties({ ServerProperties.class, SessionProperties.class })
6875
@AutoConfigureAfter({ DataSourceAutoConfiguration.class, HazelcastAutoConfiguration.class,
6976
JdbcTemplateAutoConfiguration.class, MongoDataAutoConfiguration.class,
7077
MongoReactiveDataAutoConfiguration.class, RedisAutoConfiguration.class,
@@ -78,6 +85,29 @@ public class SessionAutoConfiguration {
7885
SessionRepositoryFilterConfiguration.class })
7986
static class ServletSessionConfiguration {
8087

88+
private final ServerProperties serverProperties;
89+
90+
ServletSessionConfiguration(ServerProperties serverProperties) {
91+
this.serverProperties = serverProperties;
92+
}
93+
94+
@Bean
95+
@ConditionalOnMissingBean({ CookieSerializer.class,
96+
HeaderHttpSessionIdResolver.class })
97+
public DefaultCookieSerializer cookieSerializer() {
98+
Cookie cookie = this.serverProperties.getServlet().getSession().getCookie();
99+
DefaultCookieSerializer cookieSerializer = new DefaultCookieSerializer();
100+
PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull();
101+
map.from(cookie::getName).to(cookieSerializer::setCookieName);
102+
map.from(cookie::getDomain).to(cookieSerializer::setDomainName);
103+
map.from(cookie::getPath).to(cookieSerializer::setCookiePath);
104+
map.from(cookie::getHttpOnly).to(cookieSerializer::setUseHttpOnlyCookie);
105+
map.from(cookie::getSecure).to(cookieSerializer::setUseSecureCookie);
106+
map.from(cookie::getMaxAge).to((maxAge) -> cookieSerializer
107+
.setCookieMaxAge((int) maxAge.getSeconds()));
108+
return cookieSerializer;
109+
}
110+
81111
@Configuration
82112
@ConditionalOnMissingBean(SessionRepository.class)
83113
@Import({ ServletSessionRepositoryImplementationValidator.class,

spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/session/SessionAutoConfigurationTests.java

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import org.springframework.session.config.annotation.web.http.EnableSpringHttpSession;
3939
import org.springframework.session.web.http.CookieHttpSessionIdResolver;
4040
import org.springframework.session.web.http.DefaultCookieSerializer;
41+
import org.springframework.session.web.http.HeaderHttpSessionIdResolver;
4142
import org.springframework.session.web.http.SessionRepositoryFilter;
4243
import org.springframework.test.util.ReflectionTestUtils;
4344

@@ -185,6 +186,65 @@ public void sessionCookieConfigurationIsPickedUp() {
185186
});
186187
}
187188

189+
@Test
190+
public void autoConfiguredCookieSerializerConfiguration() {
191+
this.contextRunner.withUserConfiguration(SessionRepositoryConfiguration.class)
192+
.withPropertyValues("server.servlet.session.cookie.name=sid",
193+
"server.servlet.session.cookie.domain=spring",
194+
"server.servlet.session.cookie.path=/test",
195+
"server.servlet.session.cookie.httpOnly=false",
196+
"server.servlet.session.cookie.secure=false",
197+
"server.servlet.session.cookie.maxAge=10s")
198+
.run((context) -> {
199+
DefaultCookieSerializer cookieSerializer = context
200+
.getBean(DefaultCookieSerializer.class);
201+
assertThat(cookieSerializer).hasFieldOrPropertyWithValue("cookieName",
202+
"sid");
203+
assertThat(cookieSerializer).hasFieldOrPropertyWithValue("domainName",
204+
"spring");
205+
assertThat(cookieSerializer).hasFieldOrPropertyWithValue("cookiePath",
206+
"/test");
207+
assertThat(cookieSerializer)
208+
.hasFieldOrPropertyWithValue("useHttpOnlyCookie", false);
209+
assertThat(cookieSerializer)
210+
.hasFieldOrPropertyWithValue("useSecureCookie", false);
211+
assertThat(cookieSerializer)
212+
.hasFieldOrPropertyWithValue("cookieMaxAge", 10);
213+
});
214+
}
215+
216+
@Test
217+
public void userProvidedCookieSerializerConfiguration() {
218+
this.contextRunner
219+
.withUserConfiguration(UserProvidedCookieSerializerConfiguration.class)
220+
.withPropertyValues("server.servlet.session.cookie.name=sid")
221+
.run((context) -> {
222+
DefaultCookieSerializer cookieSerializer = context
223+
.getBean(DefaultCookieSerializer.class);
224+
assertThat(cookieSerializer).hasFieldOrPropertyWithValue("cookieName",
225+
"SESSION");
226+
});
227+
}
228+
229+
@Test
230+
public void userProvidedCookieHttpSessionStrategyConfiguration() {
231+
this.contextRunner
232+
.withUserConfiguration(
233+
UserProvidedCookieHttpSessionStrategyConfiguration.class)
234+
.run((context) -> assertThat(
235+
context.getBeansOfType(DefaultCookieSerializer.class))
236+
.isNotEmpty());
237+
}
238+
239+
@Test
240+
public void userProvidedHeaderHttpSessionStrategyConfiguration() {
241+
this.contextRunner
242+
.withUserConfiguration(
243+
UserProvidedHeaderHttpSessionStrategyConfiguration.class)
244+
.run((context) -> assertThat(
245+
context.getBeansOfType(DefaultCookieSerializer.class)).isEmpty());
246+
}
247+
188248
@Configuration
189249
@EnableSpringHttpSession
190250
static class SessionRepositoryConfiguration {
@@ -201,4 +261,40 @@ static class ServerPropertiesConfiguration {
201261

202262
}
203263

264+
@Configuration
265+
@EnableSpringHttpSession
266+
static class UserProvidedCookieSerializerConfiguration
267+
extends SessionRepositoryConfiguration {
268+
269+
@Bean
270+
public DefaultCookieSerializer myCookieSerializer() {
271+
return new DefaultCookieSerializer();
272+
}
273+
274+
}
275+
276+
@Configuration
277+
@EnableSpringHttpSession
278+
static class UserProvidedCookieHttpSessionStrategyConfiguration
279+
extends SessionRepositoryConfiguration {
280+
281+
@Bean
282+
public CookieHttpSessionIdResolver httpSessionStrategy() {
283+
return new CookieHttpSessionIdResolver();
284+
}
285+
286+
}
287+
288+
@Configuration
289+
@EnableSpringHttpSession
290+
static class UserProvidedHeaderHttpSessionStrategyConfiguration
291+
extends SessionRepositoryConfiguration {
292+
293+
@Bean
294+
public HeaderHttpSessionIdResolver httpSessionStrategy() {
295+
return HeaderHttpSessionIdResolver.xAuthToken();
296+
}
297+
298+
}
299+
204300
}

0 commit comments

Comments
 (0)