Skip to content

Commit 81d6b6d

Browse files
committed
Add Explicit SessionAuthenticationStrategy Option
SessionAuthenticationFilter requires accessing the HttpSession to do its job. Previously, there was no way to just disable the SessionAuthenticationFilter despite the fact that SessionAuthenticationStrategy is invoked by the authentication filters directly. This commit adds an option to disable SessionManagmentFilter in favor of requiring explicit SessionAuthenticationStrategy invocation already performed by the authentication filters. Closes gh-11455
1 parent 9c02e83 commit 81d6b6d

File tree

7 files changed

+69
-15
lines changed

7 files changed

+69
-15
lines changed

Diff for: config/src/main/java/org/springframework/security/config/annotation/web/configurers/SessionManagementConfigurer.java

+38-14
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,8 @@ public final class SessionManagementConfigurer<H extends HttpSecurityBuilder<H>>
135135

136136
private AuthenticationFailureHandler sessionAuthenticationFailureHandler;
137137

138+
private boolean requireExplicitAuthenticationStrategy;
139+
138140
/**
139141
* Creates a new instance
140142
* @see HttpSecurity#sessionManagement()
@@ -155,6 +157,19 @@ public SessionManagementConfigurer<H> invalidSessionUrl(String invalidSessionUrl
155157
return this;
156158
}
157159

160+
/**
161+
* Setting this means that explicit invocation of
162+
* {@link SessionAuthenticationStrategy} is required.
163+
* @param requireExplicitAuthenticationStrategy require explicit invocation of
164+
* {@link SessionAuthenticationStrategy}
165+
* @return the {@link SessionManagementConfigurer} for further customization
166+
*/
167+
public SessionManagementConfigurer<H> requireExplicitAuthenticationStrategy(
168+
boolean requireExplicitAuthenticationStrategy) {
169+
this.requireExplicitAuthenticationStrategy = requireExplicitAuthenticationStrategy;
170+
return this;
171+
}
172+
158173
/**
159174
* Setting this attribute will inject the provided invalidSessionStrategy into the
160175
* {@link SessionManagementFilter}. When an invalid session ID is submitted, the
@@ -351,6 +366,28 @@ public void init(H http) {
351366

352367
@Override
353368
public void configure(H http) {
369+
SessionManagementFilter sessionManagementFilter = createSessionManagementFilter(http);
370+
if (sessionManagementFilter != null) {
371+
http.addFilter(sessionManagementFilter);
372+
}
373+
if (isConcurrentSessionControlEnabled()) {
374+
ConcurrentSessionFilter concurrentSessionFilter = createConcurrencyFilter(http);
375+
376+
concurrentSessionFilter = postProcess(concurrentSessionFilter);
377+
http.addFilter(concurrentSessionFilter);
378+
}
379+
if (!this.enableSessionUrlRewriting) {
380+
http.addFilter(new DisableEncodeUrlFilter());
381+
}
382+
if (this.sessionPolicy == SessionCreationPolicy.ALWAYS) {
383+
http.addFilter(new ForceEagerSessionCreationFilter());
384+
}
385+
}
386+
387+
private SessionManagementFilter createSessionManagementFilter(H http) {
388+
if (this.requireExplicitAuthenticationStrategy) {
389+
return null;
390+
}
354391
SecurityContextRepository securityContextRepository = http.getSharedObject(SecurityContextRepository.class);
355392
SessionManagementFilter sessionManagementFilter = new SessionManagementFilter(securityContextRepository,
356393
getSessionAuthenticationStrategy(http));
@@ -371,20 +408,7 @@ public void configure(H http) {
371408
sessionManagementFilter.setTrustResolver(trustResolver);
372409
}
373410
sessionManagementFilter.setSecurityContextHolderStrategy(getSecurityContextHolderStrategy());
374-
sessionManagementFilter = postProcess(sessionManagementFilter);
375-
http.addFilter(sessionManagementFilter);
376-
if (isConcurrentSessionControlEnabled()) {
377-
ConcurrentSessionFilter concurrentSessionFilter = createConcurrencyFilter(http);
378-
379-
concurrentSessionFilter = postProcess(concurrentSessionFilter);
380-
http.addFilter(concurrentSessionFilter);
381-
}
382-
if (!this.enableSessionUrlRewriting) {
383-
http.addFilter(new DisableEncodeUrlFilter());
384-
}
385-
if (this.sessionPolicy == SessionCreationPolicy.ALWAYS) {
386-
http.addFilter(new ForceEagerSessionCreationFilter());
387-
}
411+
return postProcess(sessionManagementFilter);
388412
}
389413

390414
private ConcurrentSessionFilter createConcurrencyFilter(H http) {

Diff for: config/src/main/java/org/springframework/security/config/http/HttpConfigurationBuilder.java

+7-1
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,8 @@ class HttpConfigurationBuilder {
102102

103103
private static final String OPT_CHANGE_SESSION_ID = "changeSessionId";
104104

105+
private static final String ATT_AUTHENTICATION_STRATEGY_EXPLICIT_INVOCATION = "authentication-strategy-explicit-invocation";
106+
105107
private static final String ATT_INVALID_SESSION_URL = "invalid-session-url";
106108

107109
private static final String ATT_SESSION_AUTH_STRATEGY_REF = "session-authentication-strategy-ref";
@@ -537,7 +539,11 @@ else if (StringUtils.hasText(invalidSessionStrategyRef)) {
537539
sessionMgmtFilter.addPropertyReference("invalidSessionStrategy", invalidSessionStrategyRef);
538540
}
539541
sessionMgmtFilter.addConstructorArgReference(sessionAuthStratRef);
540-
this.sfpf = (RootBeanDefinition) sessionMgmtFilter.getBeanDefinition();
542+
boolean registerSessionMgmtFilter = (sessionMgmtElt == null
543+
|| !"true".equals(sessionMgmtElt.getAttribute(ATT_AUTHENTICATION_STRATEGY_EXPLICIT_INVOCATION)));
544+
if (registerSessionMgmtFilter) {
545+
this.sfpf = (RootBeanDefinition) sessionMgmtFilter.getBeanDefinition();
546+
}
541547
this.sessionStrategyRef = new RuntimeBeanReference(sessionAuthStratRef);
542548
}
543549

Diff for: config/src/main/resources/org/springframework/security/config/spring-security-5.8.rnc

+3
Original file line numberDiff line numberDiff line change
@@ -917,6 +917,9 @@ session-management =
917917
## Session-management related functionality is implemented by the addition of a SessionManagementFilter to the filter stack.
918918
element session-management {session-management.attlist, concurrency-control?}
919919

920+
session-management.attlist &=
921+
## Specifies that SessionAuthenticationStrategy must be explicitly invoked. Default false (i.e. SessionManagementFilter will implicitly invoke SessionAuthenticationStrategy).
922+
attribute authentication-strategy-explicit-invocation {xsd:boolean}?
920923
session-management.attlist &=
921924
## Indicates how session fixation protection will be applied when a user authenticates. If set to "none", no protection will be applied. "newSession" will create a new empty session, with only Spring Security-related attributes migrated. "migrateSession" will create a new session and copy all session attributes to the new session. In Servlet 3.1 (Java EE 7) and newer containers, specifying "changeSessionId" will keep the existing session and use the container-supplied session fixation protection (HttpServletRequest#changeSessionId()). Defaults to "changeSessionId" in Servlet 3.1 and newer containers, "migrateSession" in older containers. Throws an exception if "changeSessionId" is used in older containers.
922925
attribute session-fixation-protection {"none" | "newSession" | "migrateSession" | "changeSessionId" }?

Diff for: config/src/main/resources/org/springframework/security/config/spring-security-5.8.xsd

+7
Original file line numberDiff line numberDiff line change
@@ -2662,6 +2662,13 @@
26622662
</xs:attributeGroup>
26632663

26642664
<xs:attributeGroup name="session-management.attlist">
2665+
<xs:attribute name="authentication-strategy-explicit-invocation" type="xs:boolean">
2666+
<xs:annotation>
2667+
<xs:documentation>Specifies that SessionAuthenticationStrategy must be explicitly invoked. Default false
2668+
(i.e. SessionManagementFilter will implicitly invoke SessionAuthenticationStrategy).
2669+
</xs:documentation>
2670+
</xs:annotation>
2671+
</xs:attribute>
26652672
<xs:attribute name="session-fixation-protection">
26662673
<xs:annotation>
26672674
<xs:documentation>Indicates how session fixation protection will be applied when a user authenticates. If

Diff for: config/src/main/resources/org/springframework/security/config/spring-security-6.0.rnc

+3
Original file line numberDiff line numberDiff line change
@@ -889,6 +889,9 @@ session-management =
889889
## Session-management related functionality is implemented by the addition of a SessionManagementFilter to the filter stack.
890890
element session-management {session-management.attlist, concurrency-control?}
891891

892+
session-management.attlist &=
893+
## Specifies that SessionAuthenticationStrategy must be explicitly invoked. Default false (i.e. SessionManagementFilter will implicitly invoke SessionAuthenticationStrategy).
894+
attribute authentication-strategy-explicit-invocation {xsd:boolean}?
892895
session-management.attlist &=
893896
## Indicates how session fixation protection will be applied when a user authenticates. If set to "none", no protection will be applied. "newSession" will create a new empty session, with only Spring Security-related attributes migrated. "migrateSession" will create a new session and copy all session attributes to the new session. In Servlet 3.1 (Java EE 7) and newer containers, specifying "changeSessionId" will keep the existing session and use the container-supplied session fixation protection (HttpServletRequest#changeSessionId()). Defaults to "changeSessionId" in Servlet 3.1 and newer containers, "migrateSession" in older containers. Throws an exception if "changeSessionId" is used in older containers.
894897
attribute session-fixation-protection {"none" | "newSession" | "migrateSession" | "changeSessionId" }?

Diff for: config/src/main/resources/org/springframework/security/config/spring-security-6.0.xsd

+7
Original file line numberDiff line numberDiff line change
@@ -2572,6 +2572,13 @@
25722572
</xs:attributeGroup>
25732573

25742574
<xs:attributeGroup name="session-management.attlist">
2575+
<xs:attribute name="authentication-strategy-explicit-invocation" type="xs:boolean">
2576+
<xs:annotation>
2577+
<xs:documentation>Specifies that SessionAuthenticationStrategy must be explicitly invoked. Default false
2578+
(i.e. SessionManagementFilter will implicitly invoke SessionAuthenticationStrategy).
2579+
</xs:documentation>
2580+
</xs:annotation>
2581+
</xs:attribute>
25752582
<xs:attribute name="session-fixation-protection">
25762583
<xs:annotation>
25772584
<xs:documentation>Indicates how session fixation protection will be applied when a user authenticates. If

Diff for: docs/modules/ROOT/pages/servlet/appendix/namespace/http.adoc

+4
Original file line numberDiff line numberDiff line change
@@ -2066,6 +2066,10 @@ Session-management related functionality is implemented by the addition of a `Se
20662066
=== <session-management> Attributes
20672067

20682068

2069+
[[nsa-session-management-authentication-strategy-explicit-invocation]]
2070+
* **authentication-strategy-explicit-invocation**
2071+
Setting this attribute to true will mean that `SessionManagementFilter` will not be injected and explicit invocation of SessionAuthenticationStrategy is required.
2072+
20692073
[[nsa-session-management-invalid-session-url]]
20702074
* **invalid-session-url**
20712075
Setting this attribute will inject the `SessionManagementFilter` with a `SimpleRedirectInvalidSessionStrategy` configured with the attribute value.

0 commit comments

Comments
 (0)