1717package org .springframework .boot .session .autoconfigure ;
1818
1919import java .time .Duration ;
20+ import java .util .function .Supplier ;
21+
22+ import jakarta .servlet .ServletContext ;
23+ import jakarta .servlet .SessionCookieConfig ;
24+ import org .jspecify .annotations .Nullable ;
2025
2126import org .springframework .beans .factory .ObjectProvider ;
2227import org .springframework .boot .autoconfigure .AutoConfiguration ;
2530import org .springframework .boot .autoconfigure .condition .ConditionalOnBean ;
2631import org .springframework .boot .autoconfigure .condition .ConditionalOnClass ;
2732import org .springframework .boot .autoconfigure .condition .ConditionalOnMissingBean ;
33+ import org .springframework .boot .autoconfigure .condition .ConditionalOnNotWarDeployment ;
34+ import org .springframework .boot .autoconfigure .condition .ConditionalOnWarDeployment ;
2835import org .springframework .boot .autoconfigure .condition .ConditionalOnWebApplication ;
2936import org .springframework .boot .autoconfigure .condition .ConditionalOnWebApplication .Type ;
3037import org .springframework .boot .context .properties .EnableConfigurationProperties ;
4350import org .springframework .session .web .http .CookieSerializer ;
4451import org .springframework .session .web .http .DefaultCookieSerializer ;
4552import org .springframework .session .web .http .HttpSessionIdResolver ;
53+ import org .springframework .util .Assert ;
54+ import org .springframework .web .context .ServletContextAware ;
4655
4756/**
4857 * {@link EnableAutoConfiguration Auto-configuration} for Spring Session.
5867@ AutoConfiguration
5968@ ConditionalOnClass (Session .class )
6069@ ConditionalOnWebApplication
61- @ EnableConfigurationProperties ({ ServerProperties . class , SessionProperties .class } )
70+ @ EnableConfigurationProperties (SessionProperties .class )
6271public final class SessionAutoConfiguration {
6372
73+ private static Duration determineTimeout (SessionProperties sessionProperties , Supplier <Duration > fallbackTimeout ) {
74+ Duration timeout = sessionProperties .getTimeout ();
75+ return (timeout != null ) ? timeout : fallbackTimeout .get ();
76+ }
77+
6478 @ Configuration (proxyBeanMethods = false )
6579 @ ConditionalOnWebApplication (type = Type .SERVLET )
6680 @ Import (SessionRepositoryFilterConfiguration .class )
6781 static class ServletSessionConfiguration {
6882
69- @ Bean
70- @ Conditional (DefaultCookieSerializerCondition .class )
71- DefaultCookieSerializer cookieSerializer (ServerProperties serverProperties ,
72- ObjectProvider <DefaultCookieSerializerCustomizer > cookieSerializerCustomizers ) {
73- Cookie cookie = serverProperties .getServlet ().getSession ().getCookie ();
74- DefaultCookieSerializer cookieSerializer = new DefaultCookieSerializer ();
75- PropertyMapper map = PropertyMapper .get ();
76- map .from (cookie ::getName ).to (cookieSerializer ::setCookieName );
77- map .from (cookie ::getDomain ).to (cookieSerializer ::setDomainName );
78- map .from (cookie ::getPath ).to (cookieSerializer ::setCookiePath );
79- map .from (cookie ::getHttpOnly ).to (cookieSerializer ::setUseHttpOnlyCookie );
80- map .from (cookie ::getSecure ).to (cookieSerializer ::setUseSecureCookie );
81- map .from (cookie ::getMaxAge ).asInt (Duration ::getSeconds ).to (cookieSerializer ::setCookieMaxAge );
82- map .from (cookie ::getSameSite ).as (SameSite ::attributeValue ).always ().to (cookieSerializer ::setSameSite );
83- map .from (cookie ::getPartitioned ).to (cookieSerializer ::setPartitioned );
84- cookieSerializerCustomizers .orderedStream ().forEach ((customizer ) -> customizer .customize (cookieSerializer ));
85- return cookieSerializer ;
86- }
87-
8883 @ Configuration (proxyBeanMethods = false )
8984 @ ConditionalOnClass (RememberMeServices .class )
9085 static class RememberMeServicesConfiguration {
@@ -97,6 +92,90 @@ DefaultCookieSerializerCustomizer rememberMeServicesCookieSerializerCustomizer()
9792
9893 }
9994
95+ @ ConditionalOnNotWarDeployment
96+ @ EnableConfigurationProperties (ServerProperties .class )
97+ static class EmbeddedWebServerConfiguration {
98+
99+ @ Bean
100+ SessionTimeout embeddedWebServerSessionTimeout (SessionProperties sessionProperties ,
101+ ServerProperties serverProperties ) {
102+ return () -> determineTimeout (sessionProperties ,
103+ serverProperties .getServlet ().getSession ()::getTimeout );
104+ }
105+
106+ @ Bean
107+ @ Conditional (DefaultCookieSerializerCondition .class )
108+ DefaultCookieSerializer cookieSerializer (ServerProperties serverProperties ,
109+ ObjectProvider <DefaultCookieSerializerCustomizer > cookieSerializerCustomizers ) {
110+ Cookie cookie = serverProperties .getServlet ().getSession ().getCookie ();
111+ DefaultCookieSerializer cookieSerializer = new DefaultCookieSerializer ();
112+ PropertyMapper map = PropertyMapper .get ();
113+ map .from (cookie ::getName ).to (cookieSerializer ::setCookieName );
114+ map .from (cookie ::getDomain ).to (cookieSerializer ::setDomainName );
115+ map .from (cookie ::getPath ).to (cookieSerializer ::setCookiePath );
116+ map .from (cookie ::getHttpOnly ).to (cookieSerializer ::setUseHttpOnlyCookie );
117+ map .from (cookie ::getSecure ).to (cookieSerializer ::setUseSecureCookie );
118+ map .from (cookie ::getMaxAge ).asInt (Duration ::getSeconds ).to (cookieSerializer ::setCookieMaxAge );
119+ map .from (cookie ::getSameSite ).as (SameSite ::attributeValue ).always ().to (cookieSerializer ::setSameSite );
120+ map .from (cookie ::getPartitioned ).to (cookieSerializer ::setPartitioned );
121+ cookieSerializerCustomizers .orderedStream ()
122+ .forEach ((customizer ) -> customizer .customize (cookieSerializer ));
123+ return cookieSerializer ;
124+ }
125+
126+ }
127+
128+ @ ConditionalOnWarDeployment
129+ static class WarDepoymentConfiguration implements ServletContextAware {
130+
131+ private @ Nullable ServletContext servletContext ;
132+
133+ @ Override
134+ public void setServletContext (ServletContext servletContext ) {
135+ this .servletContext = servletContext ;
136+ }
137+
138+ @ Bean
139+ SessionTimeout warDeplomentSessionTimeout (SessionProperties sessionProperties ) {
140+ return sessionProperties ::getTimeout ;
141+ }
142+
143+ @ Bean
144+ @ Conditional (DefaultCookieSerializerCondition .class )
145+ DefaultCookieSerializer cookieSerializer (
146+ ObjectProvider <DefaultCookieSerializerCustomizer > cookieSerializerCustomizers ) {
147+ DefaultCookieSerializer cookieSerializer = new DefaultCookieSerializer ();
148+ PropertyMapper map = PropertyMapper .get ();
149+ Assert .notNull (this .servletContext ,
150+ "ServletContext is required for session configuration in a war deployment" );
151+ SessionCookieConfig cookie = this .servletContext .getSessionCookieConfig ();
152+ map .from (cookie ::getName ).to (cookieSerializer ::setCookieName );
153+ map .from (cookie ::getDomain ).to (cookieSerializer ::setDomainName );
154+ map .from (cookie ::getPath ).to (cookieSerializer ::setCookiePath );
155+ map .from (cookie ::isHttpOnly ).to (cookieSerializer ::setUseHttpOnlyCookie );
156+ map .from (cookie ::isSecure ).to (cookieSerializer ::setUseSecureCookie );
157+ map .from (cookie ::getMaxAge ).to (cookieSerializer ::setCookieMaxAge );
158+ map .from (cookie .getAttribute ("SameSite" )).always ().to (cookieSerializer ::setSameSite );
159+ map .from (cookie .getAttribute ("Partitioned" )).as (Boolean ::valueOf ).to (cookieSerializer ::setPartitioned );
160+ cookieSerializerCustomizers .orderedStream ()
161+ .forEach ((customizer ) -> customizer .customize (cookieSerializer ));
162+ return cookieSerializer ;
163+ }
164+
165+ }
166+
167+ }
168+
169+ @ Configuration (proxyBeanMethods = false )
170+ @ ConditionalOnWebApplication (type = Type .REACTIVE )
171+ static class ReactiveSessionConfiguration {
172+
173+ @ Bean
174+ SessionTimeout embeddedWebServerSessionTimeout (SessionProperties sessionProperties ,
175+ ServerProperties serverProperties ) {
176+ return () -> determineTimeout (sessionProperties , serverProperties .getReactive ().getSession ()::getTimeout );
177+ }
178+
100179 }
101180
102181 /**
0 commit comments