Skip to content

Commit 89f8310

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 51dc672 commit 89f8310

File tree

5 files changed

+59
-15
lines changed

5 files changed

+59
-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
@@ -103,6 +103,8 @@ class HttpConfigurationBuilder {
103103

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

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

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

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: docs/modules/ROOT/pages/servlet/appendix/namespace/http.adoc

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

22452245

2246+
[[nsa-session-management-authentication-strategy-explicit-invocation]]
2247+
* **authentication-strategy-explicit-invocation**
2248+
Setting this attribute to true will mean that `SessionManagementFilter` will not be injected and explicit invocation of SessionAuthenticationStrategy is required.
2249+
22462250
[[nsa-session-management-invalid-session-url]]
22472251
* **invalid-session-url**
22482252
Setting this attribute will inject the `SessionManagementFilter` with a `SimpleRedirectInvalidSessionStrategy` configured with the attribute value.

0 commit comments

Comments
 (0)