From 972039e65c0132b59e1b1ee682b220de25620afc Mon Sep 17 00:00:00 2001 From: Rob Winch Date: Fri, 18 Feb 2022 15:14:34 -0600 Subject: [PATCH] Add SecurityContextHolderFilter Closes gh-9635 --- .../web/builders/FilterOrderRegistration.java | 2 + ...bstractAuthenticationFilterConfigurer.java | 12 +++ .../SecurityContextConfigurer.java | 49 ++++++--- .../http/AuthenticationConfigBuilder.java | 43 +++++--- .../config/http/HttpConfigurationBuilder.java | 32 +++++- .../HttpSecurityBeanDefinitionParser.java | 4 +- .../OAuth2ClientBeanDefinitionParser.java | 15 ++- .../http/Saml2LoginBeanDefinitionParser.java | 16 ++- .../security/config/spring-security-6.0.rnc | 3 + .../security/config/spring-security-6.0.xsd | 7 ++ .../SecurityContextConfigurerTests.java | 61 ++++++++++- .../config/http/MiscHttpConfigTests.java | 33 ++++++ .../http/MiscHttpConfigTests-ExplicitSave.xml | 34 +++++++ ...ests-ExplicitSaveAndExplicitRepository.xml | 38 +++++++ .../securitycontextholderfilter.odg | Bin 0 -> 14690 bytes .../securitycontextholderfilter.png | Bin 0 -> 104385 bytes .../servlet/appendix/namespace/http.adoc | 6 ++ .../servlet/authentication/persistence.adoc | 67 +++++++++++- .../test/web/support/WebTestUtils.java | 11 +- .../context/SecurityContextHolderFilter.java | 86 ++++++++++++++++ .../SecurityContextHolderFilterTests.java | 95 ++++++++++++++++++ 21 files changed, 571 insertions(+), 43 deletions(-) create mode 100644 config/src/test/resources/org/springframework/security/config/http/MiscHttpConfigTests-ExplicitSave.xml create mode 100644 config/src/test/resources/org/springframework/security/config/http/MiscHttpConfigTests-ExplicitSaveAndExplicitRepository.xml create mode 100644 docs/modules/ROOT/assets/images/servlet/authentication/securitycontextholderfilter.odg create mode 100644 docs/modules/ROOT/assets/images/servlet/authentication/securitycontextholderfilter.png create mode 100644 web/src/main/java/org/springframework/security/web/context/SecurityContextHolderFilter.java create mode 100644 web/src/test/java/org/springframework/security/web/context/SecurityContextHolderFilterTests.java diff --git a/config/src/main/java/org/springframework/security/config/annotation/web/builders/FilterOrderRegistration.java b/config/src/main/java/org/springframework/security/config/annotation/web/builders/FilterOrderRegistration.java index f00cecd3943..ce955df3e36 100644 --- a/config/src/main/java/org/springframework/security/config/annotation/web/builders/FilterOrderRegistration.java +++ b/config/src/main/java/org/springframework/security/config/annotation/web/builders/FilterOrderRegistration.java @@ -37,6 +37,7 @@ import org.springframework.security.web.authentication.ui.DefaultLogoutPageGeneratingFilter; import org.springframework.security.web.authentication.www.BasicAuthenticationFilter; import org.springframework.security.web.authentication.www.DigestAuthenticationFilter; +import org.springframework.security.web.context.SecurityContextHolderFilter; import org.springframework.security.web.context.SecurityContextPersistenceFilter; import org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter; import org.springframework.security.web.csrf.CsrfFilter; @@ -70,6 +71,7 @@ final class FilterOrderRegistration { put(ChannelProcessingFilter.class, order.next()); order.next(); // gh-8105 put(WebAsyncManagerIntegrationFilter.class, order.next()); + put(SecurityContextHolderFilter.class, order.next()); put(SecurityContextPersistenceFilter.class, order.next()); put(HeaderWriterFilter.class, order.next()); put(CorsFilter.class, order.next()); diff --git a/config/src/main/java/org/springframework/security/config/annotation/web/configurers/AbstractAuthenticationFilterConfigurer.java b/config/src/main/java/org/springframework/security/config/annotation/web/configurers/AbstractAuthenticationFilterConfigurer.java index 507f7b85bfe..cf1d3ab7a1d 100644 --- a/config/src/main/java/org/springframework/security/config/annotation/web/configurers/AbstractAuthenticationFilterConfigurer.java +++ b/config/src/main/java/org/springframework/security/config/annotation/web/configurers/AbstractAuthenticationFilterConfigurer.java @@ -37,6 +37,7 @@ import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler; import org.springframework.security.web.authentication.WebAuthenticationDetailsSource; import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy; +import org.springframework.security.web.context.SecurityContextRepository; import org.springframework.security.web.savedrequest.RequestCache; import org.springframework.security.web.util.matcher.AndRequestMatcher; import org.springframework.security.web.util.matcher.MediaTypeRequestMatcher; @@ -144,6 +145,11 @@ public T loginProcessingUrl(String loginProcessingUrl) { return getSelf(); } + public T securityContextRepository(SecurityContextRepository securityContextRepository) { + this.authFilter.setSecurityContextRepository(securityContextRepository); + return getSelf(); + } + /** * Create the {@link RequestMatcher} given a loginProcessingUrl * @param loginProcessingUrl creates the {@link RequestMatcher} based upon the @@ -285,6 +291,12 @@ public void configure(B http) throws Exception { if (rememberMeServices != null) { this.authFilter.setRememberMeServices(rememberMeServices); } + SecurityContextConfigurer securityContextConfigurer = http.getConfigurer(SecurityContextConfigurer.class); + if (securityContextConfigurer != null && securityContextConfigurer.isRequireExplicitSave()) { + SecurityContextRepository securityContextRepository = securityContextConfigurer + .getSecurityContextRepository(); + this.authFilter.setSecurityContextRepository(securityContextRepository); + } F filter = postProcess(this.authFilter); http.addFilter(filter); } diff --git a/config/src/main/java/org/springframework/security/config/annotation/web/configurers/SecurityContextConfigurer.java b/config/src/main/java/org/springframework/security/config/annotation/web/configurers/SecurityContextConfigurer.java index 2139961a00a..4e25820d236 100644 --- a/config/src/main/java/org/springframework/security/config/annotation/web/configurers/SecurityContextConfigurer.java +++ b/config/src/main/java/org/springframework/security/config/annotation/web/configurers/SecurityContextConfigurer.java @@ -22,6 +22,7 @@ import org.springframework.security.core.context.SecurityContext; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.web.context.HttpSessionSecurityContextRepository; +import org.springframework.security.web.context.SecurityContextHolderFilter; import org.springframework.security.web.context.SecurityContextPersistenceFilter; import org.springframework.security.web.context.SecurityContextRepository; @@ -62,6 +63,8 @@ public final class SecurityContextConfigurer> extends AbstractHttpConfigurer, H> { + private boolean requireExplicitSave; + /** * Creates a new instance * @see HttpSecurity#securityContext() @@ -79,23 +82,45 @@ public SecurityContextConfigurer securityContextRepository(SecurityContextRep return this; } + public SecurityContextConfigurer requireExplicitSave(boolean requireExplicitSave) { + this.requireExplicitSave = requireExplicitSave; + return this; + } + + boolean isRequireExplicitSave() { + return this.requireExplicitSave; + } + + SecurityContextRepository getSecurityContextRepository() { + SecurityContextRepository securityContextRepository = getBuilder() + .getSharedObject(SecurityContextRepository.class); + if (securityContextRepository == null) { + securityContextRepository = new HttpSessionSecurityContextRepository(); + } + return securityContextRepository; + } + @Override @SuppressWarnings("unchecked") public void configure(H http) { - SecurityContextRepository securityContextRepository = http.getSharedObject(SecurityContextRepository.class); - if (securityContextRepository == null) { - securityContextRepository = new HttpSessionSecurityContextRepository(); + SecurityContextRepository securityContextRepository = getSecurityContextRepository(); + if (this.requireExplicitSave) { + SecurityContextHolderFilter securityContextHolderFilter = postProcess( + new SecurityContextHolderFilter(securityContextRepository)); + http.addFilter(securityContextHolderFilter); } - SecurityContextPersistenceFilter securityContextFilter = new SecurityContextPersistenceFilter( - securityContextRepository); - SessionManagementConfigurer sessionManagement = http.getConfigurer(SessionManagementConfigurer.class); - SessionCreationPolicy sessionCreationPolicy = (sessionManagement != null) - ? sessionManagement.getSessionCreationPolicy() : null; - if (SessionCreationPolicy.ALWAYS == sessionCreationPolicy) { - securityContextFilter.setForceEagerSessionCreation(true); + else { + SecurityContextPersistenceFilter securityContextFilter = new SecurityContextPersistenceFilter( + securityContextRepository); + SessionManagementConfigurer sessionManagement = http.getConfigurer(SessionManagementConfigurer.class); + SessionCreationPolicy sessionCreationPolicy = (sessionManagement != null) + ? sessionManagement.getSessionCreationPolicy() : null; + if (SessionCreationPolicy.ALWAYS == sessionCreationPolicy) { + securityContextFilter.setForceEagerSessionCreation(true); + } + securityContextFilter = postProcess(securityContextFilter); + http.addFilter(securityContextFilter); } - securityContextFilter = postProcess(securityContextFilter); - http.addFilter(securityContextFilter); } } diff --git a/config/src/main/java/org/springframework/security/config/http/AuthenticationConfigBuilder.java b/config/src/main/java/org/springframework/security/config/http/AuthenticationConfigBuilder.java index 7c04067173c..6a49b4a46f2 100644 --- a/config/src/main/java/org/springframework/security/config/http/AuthenticationConfigBuilder.java +++ b/config/src/main/java/org/springframework/security/config/http/AuthenticationConfigBuilder.java @@ -216,8 +216,8 @@ final class AuthenticationConfigBuilder { AuthenticationConfigBuilder(Element element, boolean forceAutoConfig, ParserContext pc, SessionCreationPolicy sessionPolicy, BeanReference requestCache, BeanReference authenticationManager, - BeanReference sessionStrategy, BeanReference portMapper, BeanReference portResolver, - BeanMetadataElement csrfLogoutHandler) { + BeanReference authenticationFilterSecurityContextRepositoryRef, BeanReference sessionStrategy, + BeanReference portMapper, BeanReference portResolver, BeanMetadataElement csrfLogoutHandler) { this.httpElt = element; this.pc = pc; this.requestCache = requestCache; @@ -231,9 +231,10 @@ final class AuthenticationConfigBuilder { createRememberMeFilter(authenticationManager); createBasicFilter(authenticationManager); createBearerTokenAuthenticationFilter(authenticationManager); - createFormLoginFilter(sessionStrategy, authenticationManager); - createOAuth2ClientFilters(sessionStrategy, requestCache, authenticationManager); - createSaml2LoginFilter(authenticationManager); + createFormLoginFilter(sessionStrategy, authenticationManager, authenticationFilterSecurityContextRepositoryRef); + createOAuth2ClientFilters(sessionStrategy, requestCache, authenticationManager, + authenticationFilterSecurityContextRepositoryRef); + createSaml2LoginFilter(authenticationManager, authenticationFilterSecurityContextRepositoryRef); createX509Filter(authenticationManager); createJeeFilter(authenticationManager); createLogoutFilter(); @@ -269,7 +270,8 @@ private void createRememberMeProvider(String key) { this.rememberMeProviderRef = new RuntimeBeanReference(id); } - void createFormLoginFilter(BeanReference sessionStrategy, BeanReference authManager) { + void createFormLoginFilter(BeanReference sessionStrategy, BeanReference authManager, + BeanReference authenticationFilterSecurityContextRepositoryRef) { Element formLoginElt = DomUtils.getChildElementByTagName(this.httpElt, Elements.FORM_LOGIN); RootBeanDefinition formFilter = null; if (formLoginElt != null || this.autoConfig) { @@ -285,6 +287,10 @@ void createFormLoginFilter(BeanReference sessionStrategy, BeanReference authMana if (formFilter != null) { formFilter.getPropertyValues().addPropertyValue("allowSessionCreation", this.allowSessionCreation); formFilter.getPropertyValues().addPropertyValue("authenticationManager", authManager); + if (authenticationFilterSecurityContextRepositoryRef != null) { + formFilter.getPropertyValues().addPropertyValue("securityContextRepository", + authenticationFilterSecurityContextRepositoryRef); + } // Id is required by login page filter this.formFilterId = this.pc.getReaderContext().generateBeanName(formFilter); this.pc.registerBeanComponent(new BeanComponentDefinition(formFilter, this.formFilterId)); @@ -293,13 +299,15 @@ void createFormLoginFilter(BeanReference sessionStrategy, BeanReference authMana } void createOAuth2ClientFilters(BeanReference sessionStrategy, BeanReference requestCache, - BeanReference authenticationManager) { - createOAuth2LoginFilter(sessionStrategy, authenticationManager); - createOAuth2ClientFilter(requestCache, authenticationManager); + BeanReference authenticationManager, BeanReference authenticationFilterSecurityContextRepositoryRef) { + createOAuth2LoginFilter(sessionStrategy, authenticationManager, + authenticationFilterSecurityContextRepositoryRef); + createOAuth2ClientFilter(requestCache, authenticationManager, authenticationFilterSecurityContextRepositoryRef); registerOAuth2ClientPostProcessors(); } - void createOAuth2LoginFilter(BeanReference sessionStrategy, BeanReference authManager) { + void createOAuth2LoginFilter(BeanReference sessionStrategy, BeanReference authManager, + BeanReference authenticationFilterSecurityContextRepositoryRef) { Element oauth2LoginElt = DomUtils.getChildElementByTagName(this.httpElt, Elements.OAUTH2_LOGIN); if (oauth2LoginElt == null) { return; @@ -311,6 +319,10 @@ void createOAuth2LoginFilter(BeanReference sessionStrategy, BeanReference authMa BeanDefinition defaultAuthorizedClientRepository = parser.getDefaultAuthorizedClientRepository(); registerDefaultAuthorizedClientRepositoryIfNecessary(defaultAuthorizedClientRepository); oauth2LoginFilterBean.getPropertyValues().addPropertyValue("authenticationManager", authManager); + if (authenticationFilterSecurityContextRepositoryRef != null) { + oauth2LoginFilterBean.getPropertyValues().addPropertyValue("securityContextRepository", + authenticationFilterSecurityContextRepositoryRef); + } // retrieve the other bean result BeanDefinition oauth2LoginAuthProvider = parser.getOAuth2LoginAuthenticationProvider(); @@ -340,14 +352,15 @@ void createOAuth2LoginFilter(BeanReference sessionStrategy, BeanReference authMa this.oauth2LoginOidcAuthenticationProviderRef = new RuntimeBeanReference(oauth2LoginOidcAuthProviderId); } - void createOAuth2ClientFilter(BeanReference requestCache, BeanReference authenticationManager) { + void createOAuth2ClientFilter(BeanReference requestCache, BeanReference authenticationManager, + BeanReference authenticationFilterSecurityContextRepositoryRef) { Element oauth2ClientElt = DomUtils.getChildElementByTagName(this.httpElt, Elements.OAUTH2_CLIENT); if (oauth2ClientElt == null) { return; } this.oauth2ClientEnabled = true; OAuth2ClientBeanDefinitionParser parser = new OAuth2ClientBeanDefinitionParser(requestCache, - authenticationManager); + authenticationManager, authenticationFilterSecurityContextRepositoryRef); parser.parse(oauth2ClientElt, this.pc); BeanDefinition defaultAuthorizedClientRepository = parser.getDefaultAuthorizedClientRepository(); registerDefaultAuthorizedClientRepositoryIfNecessary(defaultAuthorizedClientRepository); @@ -392,14 +405,16 @@ private void registerOAuth2ClientPostProcessors() { } } - private void createSaml2LoginFilter(BeanReference authenticationManager) { + private void createSaml2LoginFilter(BeanReference authenticationManager, + BeanReference authenticationFilterSecurityContextRepositoryRef) { Element saml2LoginElt = DomUtils.getChildElementByTagName(this.httpElt, Elements.SAML2_LOGIN); if (saml2LoginElt == null) { return; } Saml2LoginBeanDefinitionParser parser = new Saml2LoginBeanDefinitionParser(this.csrfIgnoreRequestMatchers, this.portMapper, this.portResolver, this.requestCache, this.allowSessionCreation, authenticationManager, - this.authenticationProviders, this.defaultEntryPointMappings); + authenticationFilterSecurityContextRepositoryRef, this.authenticationProviders, + this.defaultEntryPointMappings); BeanDefinition saml2WebSsoAuthenticationFilter = parser.parse(saml2LoginElt, this.pc); this.saml2AuthorizationRequestFilter = parser.getSaml2WebSsoAuthenticationRequestFilter(); diff --git a/config/src/main/java/org/springframework/security/config/http/HttpConfigurationBuilder.java b/config/src/main/java/org/springframework/security/config/http/HttpConfigurationBuilder.java index 74d12d0e947..4c859c000a3 100644 --- a/config/src/main/java/org/springframework/security/config/http/HttpConfigurationBuilder.java +++ b/config/src/main/java/org/springframework/security/config/http/HttpConfigurationBuilder.java @@ -59,6 +59,7 @@ import org.springframework.security.web.authentication.session.SessionFixationProtectionStrategy; import org.springframework.security.web.context.HttpSessionSecurityContextRepository; import org.springframework.security.web.context.NullSecurityContextRepository; +import org.springframework.security.web.context.SecurityContextHolderFilter; import org.springframework.security.web.context.SecurityContextPersistenceFilter; import org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter; import org.springframework.security.web.jaasapi.JaasApiIntegrationFilter; @@ -104,6 +105,8 @@ class HttpConfigurationBuilder { private static final String ATT_SECURITY_CONTEXT_REPOSITORY = "security-context-repository-ref"; + private static final String ATT_SECURITY_CONTEXT_EXPLICIT_SAVE = "security-context-explicit-save"; + private static final String ATT_INVALID_SESSION_STRATEGY_REF = "invalid-session-strategy-ref"; private static final String ATT_DISABLE_URL_REWRITING = "disable-url-rewriting"; @@ -202,8 +205,7 @@ class HttpConfigurationBuilder { this.sessionPolicy = !StringUtils.hasText(createSession) ? SessionCreationPolicy.IF_REQUIRED : createPolicy(createSession); createCsrfFilter(); - createSecurityContextRepository(); - createSecurityContextPersistenceFilter(); + createSecurityPersistence(); createSessionManagementFilters(); createWebAsyncManagerFilter(); createRequestCacheFilter(); @@ -279,9 +281,27 @@ static String createPath(String path, boolean lowerCase) { return lowerCase ? path.toLowerCase() : path; } + BeanReference getSecurityContextRepositoryForAuthenticationFilters() { + return (isExplicitSave()) ? this.contextRepoRef : null; + } + + private void createSecurityPersistence() { + createSecurityContextRepository(); + if (isExplicitSave()) { + createSecurityContextHolderFilter(); + } + else { + createSecurityContextPersistenceFilter(); + } + } + + private boolean isExplicitSave() { + String explicitSaveAttr = this.httpElt.getAttribute(ATT_SECURITY_CONTEXT_EXPLICIT_SAVE); + return Boolean.parseBoolean(explicitSaveAttr); + } + private void createSecurityContextPersistenceFilter() { BeanDefinitionBuilder scpf = BeanDefinitionBuilder.rootBeanDefinition(SecurityContextPersistenceFilter.class); - String disableUrlRewriting = this.httpElt.getAttribute(ATT_DISABLE_URL_REWRITING); switch (this.sessionPolicy) { case ALWAYS: scpf.addPropertyValue("forceEagerSessionCreation", Boolean.TRUE); @@ -332,6 +352,12 @@ private void createSecurityContextRepository() { this.contextRepoRef = new RuntimeBeanReference(repoRef); } + private void createSecurityContextHolderFilter() { + BeanDefinitionBuilder filter = BeanDefinitionBuilder.rootBeanDefinition(SecurityContextHolderFilter.class); + filter.addConstructorArgValue(this.contextRepoRef); + this.securityContextPersistenceFilter = filter.getBeanDefinition(); + } + private void createSessionManagementFilters() { Element sessionMgmtElt = DomUtils.getChildElementByTagName(this.httpElt, Elements.SESSION_MANAGEMENT); Element sessionCtrlElt = null; diff --git a/config/src/main/java/org/springframework/security/config/http/HttpSecurityBeanDefinitionParser.java b/config/src/main/java/org/springframework/security/config/http/HttpSecurityBeanDefinitionParser.java index 970245d1345..7d0be016ce8 100644 --- a/config/src/main/java/org/springframework/security/config/http/HttpSecurityBeanDefinitionParser.java +++ b/config/src/main/java/org/springframework/security/config/http/HttpSecurityBeanDefinitionParser.java @@ -144,9 +144,11 @@ private BeanReference createFilterChain(Element element, ParserContext pc) { boolean forceAutoConfig = isDefaultHttpConfig(element); HttpConfigurationBuilder httpBldr = new HttpConfigurationBuilder(element, forceAutoConfig, pc, portMapper, portResolver, authenticationManager); + httpBldr.getSecurityContextRepositoryForAuthenticationFilters(); AuthenticationConfigBuilder authBldr = new AuthenticationConfigBuilder(element, forceAutoConfig, pc, httpBldr.getSessionCreationPolicy(), httpBldr.getRequestCache(), authenticationManager, - httpBldr.getSessionStrategy(), portMapper, portResolver, httpBldr.getCsrfLogoutHandler()); + httpBldr.getSecurityContextRepositoryForAuthenticationFilters(), httpBldr.getSessionStrategy(), + portMapper, portResolver, httpBldr.getCsrfLogoutHandler()); httpBldr.setLogoutHandlers(authBldr.getLogoutHandlers()); httpBldr.setEntryPoint(authBldr.getEntryPointBean()); httpBldr.setAccessDeniedHandler(authBldr.getAccessDeniedHandlerBean()); diff --git a/config/src/main/java/org/springframework/security/config/http/OAuth2ClientBeanDefinitionParser.java b/config/src/main/java/org/springframework/security/config/http/OAuth2ClientBeanDefinitionParser.java index 3a72f62585d..f2c1ebd0f09 100644 --- a/config/src/main/java/org/springframework/security/config/http/OAuth2ClientBeanDefinitionParser.java +++ b/config/src/main/java/org/springframework/security/config/http/OAuth2ClientBeanDefinitionParser.java @@ -50,6 +50,8 @@ final class OAuth2ClientBeanDefinitionParser implements BeanDefinitionParser { private final BeanReference authenticationManager; + private final BeanReference authenticationFilterSecurityContextRepositoryRef; + private BeanDefinition defaultAuthorizedClientRepository; private BeanDefinition authorizationRequestRedirectFilter; @@ -58,9 +60,11 @@ final class OAuth2ClientBeanDefinitionParser implements BeanDefinitionParser { private BeanDefinition authorizationCodeAuthenticationProvider; - OAuth2ClientBeanDefinitionParser(BeanReference requestCache, BeanReference authenticationManager) { + OAuth2ClientBeanDefinitionParser(BeanReference requestCache, BeanReference authenticationManager, + BeanReference authenticationFilterSecurityContextRepositoryRef) { this.requestCache = requestCache; this.authenticationManager = authenticationManager; + this.authenticationFilterSecurityContextRepositoryRef = authenticationFilterSecurityContextRepositoryRef; } @Override @@ -92,11 +96,16 @@ public BeanDefinition parse(Element element, ParserContext parserContext) { this.authorizationRequestRedirectFilter = authorizationRequestRedirectFilterBuilder .addPropertyValue("authorizationRequestRepository", authorizationRequestRepository) .addPropertyValue("requestCache", this.requestCache).getBeanDefinition(); - this.authorizationCodeGrantFilter = BeanDefinitionBuilder + BeanDefinitionBuilder authorizationCodeGrantFilterBldr = BeanDefinitionBuilder .rootBeanDefinition(OAuth2AuthorizationCodeGrantFilter.class) .addConstructorArgValue(clientRegistrationRepository).addConstructorArgValue(authorizedClientRepository) .addConstructorArgValue(this.authenticationManager) - .addPropertyValue("authorizationRequestRepository", authorizationRequestRepository).getBeanDefinition(); + .addPropertyValue("authorizationRequestRepository", authorizationRequestRepository); + if (this.authenticationFilterSecurityContextRepositoryRef != null) { + authorizationCodeGrantFilterBldr.addPropertyValue("securityContextRepository", + this.authenticationFilterSecurityContextRepositoryRef); + } + this.authorizationCodeGrantFilter = authorizationCodeGrantFilterBldr.getBeanDefinition(); BeanMetadataElement accessTokenResponseClient = getAccessTokenResponseClient(authorizationCodeGrantElt); this.authorizationCodeAuthenticationProvider = BeanDefinitionBuilder diff --git a/config/src/main/java/org/springframework/security/config/http/Saml2LoginBeanDefinitionParser.java b/config/src/main/java/org/springframework/security/config/http/Saml2LoginBeanDefinitionParser.java index 53a2b0946b5..147166c471f 100644 --- a/config/src/main/java/org/springframework/security/config/http/Saml2LoginBeanDefinitionParser.java +++ b/config/src/main/java/org/springframework/security/config/http/Saml2LoginBeanDefinitionParser.java @@ -85,6 +85,8 @@ final class Saml2LoginBeanDefinitionParser implements BeanDefinitionParser { private final BeanReference authenticationManager; + private final BeanReference authenticationFilterSecurityContextRepositoryRef; + private final List authenticationProviders; private final Map entryPoints; @@ -97,14 +99,15 @@ final class Saml2LoginBeanDefinitionParser implements BeanDefinitionParser { Saml2LoginBeanDefinitionParser(List csrfIgnoreRequestMatchers, BeanReference portMapper, BeanReference portResolver, BeanReference requestCache, boolean allowSessionCreation, - BeanReference authenticationManager, List authenticationProviders, - Map entryPoints) { + BeanReference authenticationManager, BeanReference authenticationFilterSecurityContextRepositoryRef, + List authenticationProviders, Map entryPoints) { this.csrfIgnoreRequestMatchers = csrfIgnoreRequestMatchers; this.portMapper = portMapper; this.portResolver = portResolver; this.requestCache = requestCache; this.allowSessionCreation = allowSessionCreation; this.authenticationManager = authenticationManager; + this.authenticationFilterSecurityContextRepositoryRef = authenticationFilterSecurityContextRepositoryRef; this.authenticationProviders = authenticationProviders; this.entryPoints = entryPoints; } @@ -148,6 +151,7 @@ public BeanDefinition parse(Element element, ParserContext pc) { resolveAuthenticationSuccessHandler(element, saml2WebSsoAuthenticationFilterBuilder); resolveAuthenticationFailureHandler(element, saml2WebSsoAuthenticationFilterBuilder); resolveAuthenticationManager(element, saml2WebSsoAuthenticationFilterBuilder); + resolveSecurityContextRepository(element, saml2WebSsoAuthenticationFilterBuilder); // Configure the Saml2WebSsoAuthenticationRequestFilter this.saml2WebSsoAuthenticationRequestFilter = BeanDefinitionBuilder .rootBeanDefinition(Saml2WebSsoAuthenticationRequestFilter.class) @@ -176,6 +180,14 @@ private void resolveAuthenticationManager(Element element, } } + private void resolveSecurityContextRepository(Element element, + BeanDefinitionBuilder saml2WebSsoAuthenticationFilterBuilder) { + if (this.authenticationFilterSecurityContextRepositoryRef != null) { + saml2WebSsoAuthenticationFilterBuilder.addPropertyValue("securityContextRepository", + this.authenticationFilterSecurityContextRepositoryRef); + } + } + private void resolveLoginPage(Element element, ParserContext parserContext) { String loginPage = element.getAttribute(ATT_LOGIN_PAGE); Object source = parserContext.extractSource(element); diff --git a/config/src/main/resources/org/springframework/security/config/spring-security-6.0.rnc b/config/src/main/resources/org/springframework/security/config/spring-security-6.0.rnc index d2568fb19d9..b54f8b7d43d 100644 --- a/config/src/main/resources/org/springframework/security/config/spring-security-6.0.rnc +++ b/config/src/main/resources/org/springframework/security/config/spring-security-6.0.rnc @@ -333,6 +333,9 @@ http.attlist &= http.attlist &= ## A reference to a SecurityContextRepository bean. This can be used to customize how the SecurityContext is stored between requests. attribute security-context-repository-ref {xsd:token}? +http.attlist &= + ## Optional attribute that specifies that the SecurityContext should require explicit saving rather than being synchronized from the SecurityContextHolder. Defaults to "false". + attribute security-context-explicit-save {xsd:boolean}? http.attlist &= request-matcher? http.attlist &= diff --git a/config/src/main/resources/org/springframework/security/config/spring-security-6.0.xsd b/config/src/main/resources/org/springframework/security/config/spring-security-6.0.xsd index 5af38a04f77..9c6937292ff 100644 --- a/config/src/main/resources/org/springframework/security/config/spring-security-6.0.xsd +++ b/config/src/main/resources/org/springframework/security/config/spring-security-6.0.xsd @@ -1215,6 +1215,13 @@ + + + Optional attribute that specifies that the SecurityContext should require explicit saving + rather than being synchronized from the SecurityContextHolder. Defaults to "false". + + + Defines the strategy use for matching incoming requests. Currently the options are 'mvc' diff --git a/config/src/test/java/org/springframework/security/config/annotation/web/configurers/SecurityContextConfigurerTests.java b/config/src/test/java/org/springframework/security/config/annotation/web/configurers/SecurityContextConfigurerTests.java index f1faf2f76e5..d675f00e9bd 100644 --- a/config/src/test/java/org/springframework/security/config/annotation/web/configurers/SecurityContextConfigurerTests.java +++ b/config/src/test/java/org/springframework/security/config/annotation/web/configurers/SecurityContextConfigurerTests.java @@ -16,6 +16,10 @@ package org.springframework.security.config.annotation.web.configurers; +import java.util.List; +import java.util.stream.Collectors; + +import jakarta.servlet.Filter; import jakarta.servlet.http.HttpSession; import org.junit.jupiter.api.Test; @@ -33,8 +37,11 @@ import org.springframework.security.config.test.SpringTestContextExtension; import org.springframework.security.core.context.SecurityContext; import org.springframework.security.core.userdetails.PasswordEncodedUser; +import org.springframework.security.web.FilterChainProxy; import org.springframework.security.web.context.HttpRequestResponseHolder; +import org.springframework.security.web.context.HttpSessionSecurityContextRepository; import org.springframework.security.web.context.NullSecurityContextRepository; +import org.springframework.security.web.context.SecurityContextHolderFilter; import org.springframework.security.web.context.SecurityContextPersistenceFilter; import org.springframework.security.web.context.SecurityContextRepository; import org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter; @@ -110,6 +117,27 @@ public void requestWhenNullSecurityContextRepositoryInLambdaThenContextNotSavedI assertThat(session).isNull(); } + @Test + public void requireExplicitSave() throws Exception { + HttpSessionSecurityContextRepository repository = new HttpSessionSecurityContextRepository(); + SpringTestContext testContext = this.spring.register(RequireExplicitSaveConfig.class); + testContext.autowire(); + FilterChainProxy filterChainProxy = testContext.getContext().getBean(FilterChainProxy.class); + // @formatter:off + List> filterTypes = filterChainProxy.getFilters("/") + .stream() + .map(Filter::getClass) + .collect(Collectors.toList()); + assertThat(filterTypes) + .contains(SecurityContextHolderFilter.class) + .doesNotContain(SecurityContextPersistenceFilter.class); + // @formatter:on + MvcResult mvcResult = this.mvc.perform(formLogin()).andReturn(); + SecurityContext securityContext = repository + .loadContext(new HttpRequestResponseHolder(mvcResult.getRequest(), mvcResult.getResponse())); + assertThat(securityContext.getAuthentication()).isNotNull(); + } + @EnableWebSecurity static class ObjectPostProcessorConfig extends WebSecurityConfigurerAdapter { @@ -241,14 +269,39 @@ protected void configure(AuthenticationManagerBuilder auth) throws Exception { @EnableWebSecurity static class NullSecurityContextRepositoryInLambdaConfig extends WebSecurityConfigurerAdapter { + @Override + protected void configure(HttpSecurity http) throws Exception { + // @formatter:off + http + .formLogin(withDefaults()) + .securityContext((securityContext) -> + securityContext + .securityContextRepository(new NullSecurityContextRepository()) + ); + // @formatter:on + } + + @Override + protected void configure(AuthenticationManagerBuilder auth) throws Exception { + // @formatter:off + auth + .inMemoryAuthentication() + .withUser(PasswordEncodedUser.user()); + // @formatter:on + } + + } + + @EnableWebSecurity + static class RequireExplicitSaveConfig extends WebSecurityConfigurerAdapter { + @Override protected void configure(HttpSecurity http) throws Exception { // @formatter:off http .formLogin(withDefaults()) - .securityContext((securityContext) -> - securityContext - .securityContextRepository(new NullSecurityContextRepository()) + .securityContext((securityContext) -> securityContext + .requireExplicitSave(true) ); // @formatter:on } @@ -258,7 +311,7 @@ protected void configure(AuthenticationManagerBuilder auth) throws Exception { // @formatter:off auth .inMemoryAuthentication() - .withUser(PasswordEncodedUser.user()); + .withUser(PasswordEncodedUser.user()); // @formatter:on } diff --git a/config/src/test/java/org/springframework/security/config/http/MiscHttpConfigTests.java b/config/src/test/java/org/springframework/security/config/http/MiscHttpConfigTests.java index 63d7f0886dd..5b9255996ab 100644 --- a/config/src/test/java/org/springframework/security/config/http/MiscHttpConfigTests.java +++ b/config/src/test/java/org/springframework/security/config/http/MiscHttpConfigTests.java @@ -121,9 +121,11 @@ import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; +import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestBuilders.formLogin; import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf; import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.httpBasic; import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.x509; +import static org.springframework.security.test.web.servlet.response.SecurityMockMvcResultMatchers.authenticated; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; @@ -461,6 +463,37 @@ public void getWhenAuthenticatingThenConsultsCustomSecurityContextRepository() t any(HttpServletResponse.class)); } + @Test + public void getWhenExplicitSaveAndRepositoryAndAuthenticatingThenConsultsCustomSecurityContextRepository() + throws Exception { + this.spring.configLocations(xml("ExplicitSaveAndExplicitRepository")).autowire(); + SecurityContextRepository repository = this.spring.getContext().getBean(SecurityContextRepository.class); + SecurityContext context = new SecurityContextImpl(new TestingAuthenticationToken("user", "password")); + given(repository.loadContext(any(HttpRequestResponseHolder.class))).willReturn(context); + // @formatter:off + MvcResult result = this.mvc.perform(formLogin()) + .andExpect(status().is3xxRedirection()) + .andExpect(authenticated()) + .andReturn(); + // @formatter:on + verify(repository, atLeastOnce()).saveContext(any(SecurityContext.class), any(HttpServletRequest.class), + any(HttpServletResponse.class)); + } + + @Test + public void getWhenExplicitSaveAndExplicitSaveAndAuthenticatingThenConsultsCustomSecurityContextRepository() + throws Exception { + this.spring.configLocations(xml("ExplicitSave")).autowire(); + SecurityContextRepository repository = this.spring.getContext().getBean(SecurityContextRepository.class); + // @formatter:off + MvcResult result = this.mvc.perform(formLogin()) + .andExpect(status().is3xxRedirection()) + .andReturn(); + // @formatter:on + assertThat(repository.loadContext(new HttpRequestResponseHolder(result.getRequest(), result.getResponse())) + .getAuthentication()).isNotNull(); + } + @Test public void getWhenUsingInterceptUrlExpressionsThenAuthorizesAccordingly() throws Exception { this.spring.configLocations(xml("InterceptUrlExpressions")).autowire(); diff --git a/config/src/test/resources/org/springframework/security/config/http/MiscHttpConfigTests-ExplicitSave.xml b/config/src/test/resources/org/springframework/security/config/http/MiscHttpConfigTests-ExplicitSave.xml new file mode 100644 index 00000000000..381fff8dca7 --- /dev/null +++ b/config/src/test/resources/org/springframework/security/config/http/MiscHttpConfigTests-ExplicitSave.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + diff --git a/config/src/test/resources/org/springframework/security/config/http/MiscHttpConfigTests-ExplicitSaveAndExplicitRepository.xml b/config/src/test/resources/org/springframework/security/config/http/MiscHttpConfigTests-ExplicitSaveAndExplicitRepository.xml new file mode 100644 index 00000000000..4406065ff68 --- /dev/null +++ b/config/src/test/resources/org/springframework/security/config/http/MiscHttpConfigTests-ExplicitSaveAndExplicitRepository.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + diff --git a/docs/modules/ROOT/assets/images/servlet/authentication/securitycontextholderfilter.odg b/docs/modules/ROOT/assets/images/servlet/authentication/securitycontextholderfilter.odg new file mode 100644 index 0000000000000000000000000000000000000000..95247c4ba98d6e4047cd8e913e6933070faab8c2 GIT binary patch literal 14690 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 PA0Mg@3r)!UyY~M9Cy^TW literal 0 HcmV?d00001 diff --git a/docs/modules/ROOT/assets/images/servlet/authentication/securitycontextholderfilter.png b/docs/modules/ROOT/assets/images/servlet/authentication/securitycontextholderfilter.png new file mode 100644 index 0000000000000000000000000000000000000000..25159f0c45f7cb7259dca3633e8076ed9eae741f GIT binary patch literal 104385 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 mui|@O{bUaBzIw& securityContext + .securityContextRepository(new RequestAttributeSecurityContextRepository()) + ); + return http.build(); +} +---- + +.XML +[source,xml,role="secondary"] +---- + + + + +---- +==== + + +[[securitycontextpersistencefilter]] == SecurityContextPersistenceFilter The {security-api-url}org/springframework/security/web/context/SecurityContextPersistenceFilter.html[`SecurityContextPersistenceFilter`] is responsible for persisting the `SecurityContext` between requests using the xref::servlet/authentication/persistence.adoc#securitycontextrepository[`SecurityContextRepository`]. @@ -104,4 +132,41 @@ For example, if a redirect is sent to the client the response is immediately wri This means that establishing an `HttpSession` would not be possible in step 3 because the session id could not be included in the already written response. Another situation that can happen is that if a client authenticates successfully, the response is committed before `SecurityContextPersistenceFilter` completes, and the client makes a second request before the `SecurityContextPersistenceFilter` completes the wrong authentication could be present in the second request. -To avoid these problems, the `SecurityContextPersistenceFilter` wraps both the `HttpServletRequest` and the `HttpServletResponse` to detect if the `SecurityContext` has changed and if so save the `SecurityContext` just before the response is committed. \ No newline at end of file +To avoid these problems, the `SecurityContextPersistenceFilter` wraps both the `HttpServletRequest` and the `HttpServletResponse` to detect if the `SecurityContext` has changed and if so save the `SecurityContext` just before the response is committed. + +[[securitycontextholderfilter]] +== SecurityContextHolderFilter + +The {security-api-url}org/springframework/security/web/context/SecurityContextHolderFilter.html[`SecurityContextHolderFilter`] is responsible for loading the `SecurityContext` between requests using the xref::servlet/authentication/persistence.adoc#securitycontextrepository[`SecurityContextRepository`]. + +image::{figures}/securitycontextholderfilter.png[] + +<1> Before running the rest of the application, `SecurityContextHolderFilter` loads the `SecurityContext` from the `SecurityContextRepository` and sets it on the `SecurityContextHolder`. +<2> Next, the application is ran. + +Unlike, xref:servlet/authentication/persistence.adoc#securitycontextpersistencefilter[`SecurityContextPersisteneFilter`], `SecurityContextHolderFilter` only loads the `SecurityContext` it does not save the `SecurityContext`. +This means that when using `SecurityContextHolderFilter`, it is required that the `SecurityContext` is explicitly saved. + +.Explicit Saving of SecurityContext +==== +.Java +[source,java,role="primary"] +---- +public SecurityFilterChain filterChain(HttpSecurity http) { + http + // ... + .securityContext((securityContext) -> securityContext + .requireExplicitSave(true) + ); + return http.build(); +} +---- + +.XML +[source,xml,role="secondary"] +---- + + + +---- +==== \ No newline at end of file diff --git a/test/src/main/java/org/springframework/security/test/web/support/WebTestUtils.java b/test/src/main/java/org/springframework/security/test/web/support/WebTestUtils.java index 8fe7a31ffa7..98519935a0a 100644 --- a/test/src/main/java/org/springframework/security/test/web/support/WebTestUtils.java +++ b/test/src/main/java/org/springframework/security/test/web/support/WebTestUtils.java @@ -26,6 +26,7 @@ import org.springframework.security.config.BeanIds; import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer; import org.springframework.security.web.context.HttpSessionSecurityContextRepository; +import org.springframework.security.web.context.SecurityContextHolderFilter; import org.springframework.security.web.context.SecurityContextPersistenceFilter; import org.springframework.security.web.context.SecurityContextRepository; import org.springframework.security.web.csrf.CsrfFilter; @@ -61,10 +62,14 @@ private WebTestUtils() { */ public static SecurityContextRepository getSecurityContextRepository(HttpServletRequest request) { SecurityContextPersistenceFilter filter = findFilter(request, SecurityContextPersistenceFilter.class); - if (filter == null) { - return DEFAULT_CONTEXT_REPO; + if (filter != null) { + return (SecurityContextRepository) ReflectionTestUtils.getField(filter, "repo"); + } + SecurityContextHolderFilter holderFilter = findFilter(request, SecurityContextHolderFilter.class); + if (holderFilter != null) { + return (SecurityContextRepository) ReflectionTestUtils.getField(holderFilter, "securityContextRepository"); } - return (SecurityContextRepository) ReflectionTestUtils.getField(filter, "repo"); + return DEFAULT_CONTEXT_REPO; } /** diff --git a/web/src/main/java/org/springframework/security/web/context/SecurityContextHolderFilter.java b/web/src/main/java/org/springframework/security/web/context/SecurityContextHolderFilter.java new file mode 100644 index 00000000000..4aba0d3bf94 --- /dev/null +++ b/web/src/main/java/org/springframework/security/web/context/SecurityContextHolderFilter.java @@ -0,0 +1,86 @@ +/* + * Copyright 2002-2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.security.web.context; + +import java.io.IOException; + +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + +import org.springframework.security.core.context.SecurityContext; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.util.Assert; +import org.springframework.web.filter.OncePerRequestFilter; + +/** + * A {@link jakarta.servlet.Filter} that uses the {@link SecurityContextRepository} to + * obtain the {@link SecurityContext} and set it on the {@link SecurityContextHolder}. + * This is similar to {@link SecurityContextPersistenceFilter} except that the + * {@link SecurityContextRepository#saveContext(SecurityContext, HttpServletRequest, HttpServletResponse)} + * must be explicitly invoked to save the {@link SecurityContext}. This improves the + * efficiency and provides better flexibility by allowing different authentication + * mechanisms to choose individually if authentication should be persisted. + * + * @author Rob Winch + * @since 5.7 + */ +public class SecurityContextHolderFilter extends OncePerRequestFilter { + + private final SecurityContextRepository securityContextRepository; + + private boolean shouldNotFilterErrorDispatch; + + /** + * Creates a new instance. + * @param securityContextRepository the repository to use. Cannot be null. + */ + public SecurityContextHolderFilter(SecurityContextRepository securityContextRepository) { + Assert.notNull(securityContextRepository, "securityContextRepository cannot be null"); + this.securityContextRepository = securityContextRepository; + } + + @Override + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) + throws ServletException, IOException { + SecurityContext securityContext = this.securityContextRepository + .loadContext(new HttpRequestResponseHolder(request, response)); + try { + SecurityContextHolder.setContext(securityContext); + filterChain.doFilter(request, response); + } + finally { + SecurityContextHolder.clearContext(); + } + } + + @Override + protected boolean shouldNotFilterErrorDispatch() { + return this.shouldNotFilterErrorDispatch; + } + + /** + * Disables {@link SecurityContextHolderFilter} for error dispatch. + * @param shouldNotFilterErrorDispatch if the Filter should be disabled for error + * dispatch. Default is false. + */ + public void setShouldNotFilterErrorDispatch(boolean shouldNotFilterErrorDispatch) { + this.shouldNotFilterErrorDispatch = shouldNotFilterErrorDispatch; + } + +} diff --git a/web/src/test/java/org/springframework/security/web/context/SecurityContextHolderFilterTests.java b/web/src/test/java/org/springframework/security/web/context/SecurityContextHolderFilterTests.java new file mode 100644 index 00000000000..b309cab5e9f --- /dev/null +++ b/web/src/test/java/org/springframework/security/web/context/SecurityContextHolderFilterTests.java @@ -0,0 +1,95 @@ +/* + * Copyright 2002-2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.security.web.context; + +import jakarta.servlet.FilterChain; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import org.springframework.security.authentication.TestAuthentication; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContext; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.context.SecurityContextImpl; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.BDDMockito.given; + +@ExtendWith(MockitoExtension.class) +class SecurityContextHolderFilterTests { + + @Mock + private SecurityContextRepository repository; + + @Mock + private HttpServletRequest request; + + @Mock + private HttpServletResponse response; + + @Mock + private FilterChain chain; + + @Captor + private ArgumentCaptor requestResponse; + + private SecurityContextHolderFilter filter; + + @BeforeEach + void setup() { + this.filter = new SecurityContextHolderFilter(this.repository); + } + + @AfterEach + void cleanup() { + SecurityContextHolder.clearContext(); + } + + @Test + void doFilterThenSetsAndClearsSecurityContextHolder() throws Exception { + Authentication authentication = TestAuthentication.authenticatedUser(); + SecurityContext expectedContext = new SecurityContextImpl(authentication); + given(this.repository.loadContext(this.requestResponse.capture())).willReturn(expectedContext); + FilterChain filterChain = (request, response) -> assertThat(SecurityContextHolder.getContext()) + .isEqualTo(expectedContext); + + this.filter.doFilter(this.request, this.response, filterChain); + + assertThat(SecurityContextHolder.getContext()).isEqualTo(SecurityContextHolder.createEmptyContext()); + } + + @Test + void shouldNotFilterErrorDispatchWhenDefault() { + assertThat(this.filter.shouldNotFilterErrorDispatch()).isFalse(); + } + + @Test + void shouldNotFilterErrorDispatchWhenOverridden() { + this.filter.setShouldNotFilterErrorDispatch(true); + assertThat(this.filter.shouldNotFilterErrorDispatch()).isTrue(); + } + +}