mirror of
https://github.com/spring-projects/spring-security.git
synced 2025-06-01 09:42:13 +00:00
ForceEagerSessionCreationFilter
Closes gh-11109
This commit is contained in:
parent
9601efd341
commit
9a9a43a0c0
@ -42,6 +42,7 @@ import org.springframework.security.web.savedrequest.RequestCacheAwareFilter;
|
|||||||
import org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter;
|
import org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter;
|
||||||
import org.springframework.security.web.session.ConcurrentSessionFilter;
|
import org.springframework.security.web.session.ConcurrentSessionFilter;
|
||||||
import org.springframework.security.web.session.DisableEncodeUrlFilter;
|
import org.springframework.security.web.session.DisableEncodeUrlFilter;
|
||||||
|
import org.springframework.security.web.session.ForceEagerSessionCreationFilter;
|
||||||
import org.springframework.security.web.session.SessionManagementFilter;
|
import org.springframework.security.web.session.SessionManagementFilter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -124,6 +125,7 @@ public interface HttpSecurityBuilder<H extends HttpSecurityBuilder<H>>
|
|||||||
* The ordering of the Filters is:
|
* The ordering of the Filters is:
|
||||||
*
|
*
|
||||||
* <ul>
|
* <ul>
|
||||||
|
* <li>{@link ForceEagerSessionCreationFilter}</li>
|
||||||
* <li>{@link DisableEncodeUrlFilter}</li>
|
* <li>{@link DisableEncodeUrlFilter}</li>
|
||||||
* <li>{@link ChannelProcessingFilter}</li>
|
* <li>{@link ChannelProcessingFilter}</li>
|
||||||
* <li>{@link SecurityContextPersistenceFilter}</li>
|
* <li>{@link SecurityContextPersistenceFilter}</li>
|
||||||
|
@ -47,6 +47,7 @@ import org.springframework.security.web.savedrequest.RequestCacheAwareFilter;
|
|||||||
import org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter;
|
import org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter;
|
||||||
import org.springframework.security.web.session.ConcurrentSessionFilter;
|
import org.springframework.security.web.session.ConcurrentSessionFilter;
|
||||||
import org.springframework.security.web.session.DisableEncodeUrlFilter;
|
import org.springframework.security.web.session.DisableEncodeUrlFilter;
|
||||||
|
import org.springframework.security.web.session.ForceEagerSessionCreationFilter;
|
||||||
import org.springframework.security.web.session.SessionManagementFilter;
|
import org.springframework.security.web.session.SessionManagementFilter;
|
||||||
import org.springframework.web.filter.CorsFilter;
|
import org.springframework.web.filter.CorsFilter;
|
||||||
|
|
||||||
@ -70,6 +71,7 @@ final class FilterOrderRegistration {
|
|||||||
FilterOrderRegistration() {
|
FilterOrderRegistration() {
|
||||||
Step order = new Step(INITIAL_ORDER, ORDER_STEP);
|
Step order = new Step(INITIAL_ORDER, ORDER_STEP);
|
||||||
put(DisableEncodeUrlFilter.class, order.next());
|
put(DisableEncodeUrlFilter.class, order.next());
|
||||||
|
put(ForceEagerSessionCreationFilter.class, order.next());
|
||||||
put(ChannelProcessingFilter.class, order.next());
|
put(ChannelProcessingFilter.class, order.next());
|
||||||
order.next(); // gh-8105
|
order.next(); // gh-8105
|
||||||
put(WebAsyncManagerIntegrationFilter.class, order.next());
|
put(WebAsyncManagerIntegrationFilter.class, order.next());
|
||||||
|
@ -25,6 +25,7 @@ import org.springframework.security.web.context.HttpSessionSecurityContextReposi
|
|||||||
import org.springframework.security.web.context.SecurityContextHolderFilter;
|
import org.springframework.security.web.context.SecurityContextHolderFilter;
|
||||||
import org.springframework.security.web.context.SecurityContextPersistenceFilter;
|
import org.springframework.security.web.context.SecurityContextPersistenceFilter;
|
||||||
import org.springframework.security.web.context.SecurityContextRepository;
|
import org.springframework.security.web.context.SecurityContextRepository;
|
||||||
|
import org.springframework.security.web.session.ForceEagerSessionCreationFilter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allows persisting and restoring of the {@link SecurityContext} found on the
|
* Allows persisting and restoring of the {@link SecurityContext} found on the
|
||||||
@ -117,6 +118,7 @@ public final class SecurityContextConfigurer<H extends HttpSecurityBuilder<H>>
|
|||||||
? sessionManagement.getSessionCreationPolicy() : null;
|
? sessionManagement.getSessionCreationPolicy() : null;
|
||||||
if (SessionCreationPolicy.ALWAYS == sessionCreationPolicy) {
|
if (SessionCreationPolicy.ALWAYS == sessionCreationPolicy) {
|
||||||
securityContextFilter.setForceEagerSessionCreation(true);
|
securityContextFilter.setForceEagerSessionCreation(true);
|
||||||
|
http.addFilter(postProcess(new ForceEagerSessionCreationFilter()));
|
||||||
}
|
}
|
||||||
securityContextFilter = postProcess(securityContextFilter);
|
securityContextFilter = postProcess(securityContextFilter);
|
||||||
http.addFilter(securityContextFilter);
|
http.addFilter(securityContextFilter);
|
||||||
|
@ -53,6 +53,7 @@ import org.springframework.security.web.savedrequest.NullRequestCache;
|
|||||||
import org.springframework.security.web.savedrequest.RequestCache;
|
import org.springframework.security.web.savedrequest.RequestCache;
|
||||||
import org.springframework.security.web.session.ConcurrentSessionFilter;
|
import org.springframework.security.web.session.ConcurrentSessionFilter;
|
||||||
import org.springframework.security.web.session.DisableEncodeUrlFilter;
|
import org.springframework.security.web.session.DisableEncodeUrlFilter;
|
||||||
|
import org.springframework.security.web.session.ForceEagerSessionCreationFilter;
|
||||||
import org.springframework.security.web.session.InvalidSessionStrategy;
|
import org.springframework.security.web.session.InvalidSessionStrategy;
|
||||||
import org.springframework.security.web.session.SessionInformationExpiredStrategy;
|
import org.springframework.security.web.session.SessionInformationExpiredStrategy;
|
||||||
import org.springframework.security.web.session.SessionManagementFilter;
|
import org.springframework.security.web.session.SessionManagementFilter;
|
||||||
@ -380,6 +381,9 @@ public final class SessionManagementConfigurer<H extends HttpSecurityBuilder<H>>
|
|||||||
if (!this.enableSessionUrlRewriting) {
|
if (!this.enableSessionUrlRewriting) {
|
||||||
http.addFilter(new DisableEncodeUrlFilter());
|
http.addFilter(new DisableEncodeUrlFilter());
|
||||||
}
|
}
|
||||||
|
if (this.sessionPolicy == SessionCreationPolicy.ALWAYS) {
|
||||||
|
http.addFilter(new ForceEagerSessionCreationFilter());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private ConcurrentSessionFilter createConcurrencyFilter(H http) {
|
private ConcurrentSessionFilter createConcurrencyFilter(H http) {
|
||||||
|
@ -68,6 +68,7 @@ import org.springframework.security.web.savedrequest.RequestCacheAwareFilter;
|
|||||||
import org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter;
|
import org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter;
|
||||||
import org.springframework.security.web.session.ConcurrentSessionFilter;
|
import org.springframework.security.web.session.ConcurrentSessionFilter;
|
||||||
import org.springframework.security.web.session.DisableEncodeUrlFilter;
|
import org.springframework.security.web.session.DisableEncodeUrlFilter;
|
||||||
|
import org.springframework.security.web.session.ForceEagerSessionCreationFilter;
|
||||||
import org.springframework.security.web.session.SessionManagementFilter;
|
import org.springframework.security.web.session.SessionManagementFilter;
|
||||||
import org.springframework.security.web.session.SimpleRedirectInvalidSessionStrategy;
|
import org.springframework.security.web.session.SimpleRedirectInvalidSessionStrategy;
|
||||||
import org.springframework.security.web.session.SimpleRedirectSessionInformationExpiredStrategy;
|
import org.springframework.security.web.session.SimpleRedirectSessionInformationExpiredStrategy;
|
||||||
@ -147,6 +148,8 @@ class HttpConfigurationBuilder {
|
|||||||
|
|
||||||
private BeanDefinition securityContextPersistenceFilter;
|
private BeanDefinition securityContextPersistenceFilter;
|
||||||
|
|
||||||
|
private BeanDefinition forceEagerSessionCreationFilter;
|
||||||
|
|
||||||
private BeanReference contextRepoRef;
|
private BeanReference contextRepoRef;
|
||||||
|
|
||||||
private BeanReference sessionRegistryRef;
|
private BeanReference sessionRegistryRef;
|
||||||
@ -206,6 +209,7 @@ class HttpConfigurationBuilder {
|
|||||||
String createSession = element.getAttribute(ATT_CREATE_SESSION);
|
String createSession = element.getAttribute(ATT_CREATE_SESSION);
|
||||||
this.sessionPolicy = !StringUtils.hasText(createSession) ? SessionCreationPolicy.IF_REQUIRED
|
this.sessionPolicy = !StringUtils.hasText(createSession) ? SessionCreationPolicy.IF_REQUIRED
|
||||||
: createPolicy(createSession);
|
: createPolicy(createSession);
|
||||||
|
createForceEagerSessionCreationFilter();
|
||||||
createDisableEncodeUrlFilter();
|
createDisableEncodeUrlFilter();
|
||||||
createCsrfFilter();
|
createCsrfFilter();
|
||||||
createSecurityPersistence();
|
createSecurityPersistence();
|
||||||
@ -303,6 +307,12 @@ class HttpConfigurationBuilder {
|
|||||||
return Boolean.parseBoolean(explicitSaveAttr);
|
return Boolean.parseBoolean(explicitSaveAttr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void createForceEagerSessionCreationFilter() {
|
||||||
|
if (this.sessionPolicy == SessionCreationPolicy.ALWAYS) {
|
||||||
|
this.forceEagerSessionCreationFilter = new RootBeanDefinition(ForceEagerSessionCreationFilter.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void createSecurityContextPersistenceFilter() {
|
private void createSecurityContextPersistenceFilter() {
|
||||||
BeanDefinitionBuilder scpf = BeanDefinitionBuilder.rootBeanDefinition(SecurityContextPersistenceFilter.class);
|
BeanDefinitionBuilder scpf = BeanDefinitionBuilder.rootBeanDefinition(SecurityContextPersistenceFilter.class);
|
||||||
switch (this.sessionPolicy) {
|
switch (this.sessionPolicy) {
|
||||||
@ -767,6 +777,10 @@ class HttpConfigurationBuilder {
|
|||||||
|
|
||||||
List<OrderDecorator> getFilters() {
|
List<OrderDecorator> getFilters() {
|
||||||
List<OrderDecorator> filters = new ArrayList<>();
|
List<OrderDecorator> filters = new ArrayList<>();
|
||||||
|
if (this.forceEagerSessionCreationFilter != null) {
|
||||||
|
filters.add(new OrderDecorator(this.forceEagerSessionCreationFilter,
|
||||||
|
SecurityFilters.FORCE_EAGER_SESSION_FILTER));
|
||||||
|
}
|
||||||
if (this.disableUrlRewriteFilter != null) {
|
if (this.disableUrlRewriteFilter != null) {
|
||||||
filters.add(new OrderDecorator(this.disableUrlRewriteFilter, SecurityFilters.DISABLE_ENCODE_URL_FILTER));
|
filters.add(new OrderDecorator(this.disableUrlRewriteFilter, SecurityFilters.DISABLE_ENCODE_URL_FILTER));
|
||||||
}
|
}
|
||||||
|
@ -31,6 +31,8 @@ enum SecurityFilters {
|
|||||||
|
|
||||||
DISABLE_ENCODE_URL_FILTER,
|
DISABLE_ENCODE_URL_FILTER,
|
||||||
|
|
||||||
|
FORCE_EAGER_SESSION_FILTER,
|
||||||
|
|
||||||
CHANNEL_FILTER,
|
CHANNEL_FILTER,
|
||||||
|
|
||||||
SECURITY_CONTEXT_FILTER,
|
SECURITY_CONTEXT_FILTER,
|
||||||
|
@ -1290,4 +1290,4 @@ position =
|
|||||||
## The explicit position at which the custom-filter should be placed in the chain. Use if you are replacing a standard filter.
|
## The explicit position at which the custom-filter should be placed in the chain. Use if you are replacing a standard filter.
|
||||||
attribute position {named-security-filter}
|
attribute position {named-security-filter}
|
||||||
|
|
||||||
named-security-filter = "FIRST" | "DISABLE_ENCODE_URL_FILTER" | "CHANNEL_FILTER" | "SECURITY_CONTEXT_FILTER" | "CONCURRENT_SESSION_FILTER" | "WEB_ASYNC_MANAGER_FILTER" | "HEADERS_FILTER" | "CORS_FILTER" | "SAML2_LOGOUT_REQUEST_FILTER" | "SAML2_LOGOUT_RESPONSE_FILTER" | "CSRF_FILTER" | "SAML2_LOGOUT_FILTER" | "LOGOUT_FILTER" | "OAUTH2_AUTHORIZATION_REQUEST_FILTER" | "SAML2_AUTHENTICATION_REQUEST_FILTER" | "X509_FILTER" | "PRE_AUTH_FILTER" | "CAS_FILTER" | "OAUTH2_LOGIN_FILTER" | "SAML2_AUTHENTICATION_FILTER" | "FORM_LOGIN_FILTER" | "LOGIN_PAGE_FILTER" |"LOGOUT_PAGE_FILTER" | "DIGEST_AUTH_FILTER" | "BEARER_TOKEN_AUTH_FILTER" | "BASIC_AUTH_FILTER" | "REQUEST_CACHE_FILTER" | "SERVLET_API_SUPPORT_FILTER" | "JAAS_API_SUPPORT_FILTER" | "REMEMBER_ME_FILTER" | "ANONYMOUS_FILTER" | "OAUTH2_AUTHORIZATION_CODE_GRANT_FILTER" | "WELL_KNOWN_CHANGE_PASSWORD_REDIRECT_FILTER" | "SESSION_MANAGEMENT_FILTER" | "EXCEPTION_TRANSLATION_FILTER" | "FILTER_SECURITY_INTERCEPTOR" | "SWITCH_USER_FILTER" | "LAST"
|
named-security-filter = "FIRST" | "DISABLE_ENCODE_URL_FILTER" | "FORCE_EAGER_SESSION_FILTER" | "CHANNEL_FILTER" | "SECURITY_CONTEXT_FILTER" | "CONCURRENT_SESSION_FILTER" | "WEB_ASYNC_MANAGER_FILTER" | "HEADERS_FILTER" | "CORS_FILTER" | "SAML2_LOGOUT_REQUEST_FILTER" | "SAML2_LOGOUT_RESPONSE_FILTER" | "CSRF_FILTER" | "SAML2_LOGOUT_FILTER" | "LOGOUT_FILTER" | "OAUTH2_AUTHORIZATION_REQUEST_FILTER" | "SAML2_AUTHENTICATION_REQUEST_FILTER" | "X509_FILTER" | "PRE_AUTH_FILTER" | "CAS_FILTER" | "OAUTH2_LOGIN_FILTER" | "SAML2_AUTHENTICATION_FILTER" | "FORM_LOGIN_FILTER" | "LOGIN_PAGE_FILTER" |"LOGOUT_PAGE_FILTER" | "DIGEST_AUTH_FILTER" | "BEARER_TOKEN_AUTH_FILTER" | "BASIC_AUTH_FILTER" | "REQUEST_CACHE_FILTER" | "SERVLET_API_SUPPORT_FILTER" | "JAAS_API_SUPPORT_FILTER" | "REMEMBER_ME_FILTER" | "ANONYMOUS_FILTER" | "OAUTH2_AUTHORIZATION_CODE_GRANT_FILTER" | "WELL_KNOWN_CHANGE_PASSWORD_REDIRECT_FILTER" | "SESSION_MANAGEMENT_FILTER" | "EXCEPTION_TRANSLATION_FILTER" | "FILTER_SECURITY_INTERCEPTOR" | "SWITCH_USER_FILTER" | "LAST"
|
||||||
|
@ -3632,6 +3632,7 @@
|
|||||||
<xs:restriction base="xs:token">
|
<xs:restriction base="xs:token">
|
||||||
<xs:enumeration value="FIRST"/>
|
<xs:enumeration value="FIRST"/>
|
||||||
<xs:enumeration value="DISABLE_ENCODE_URL_FILTER"/>
|
<xs:enumeration value="DISABLE_ENCODE_URL_FILTER"/>
|
||||||
|
<xs:enumeration value="FORCE_EAGER_SESSION_FILTER"/>
|
||||||
<xs:enumeration value="CHANNEL_FILTER"/>
|
<xs:enumeration value="CHANNEL_FILTER"/>
|
||||||
<xs:enumeration value="SECURITY_CONTEXT_FILTER"/>
|
<xs:enumeration value="SECURITY_CONTEXT_FILTER"/>
|
||||||
<xs:enumeration value="CONCURRENT_SESSION_FILTER"/>
|
<xs:enumeration value="CONCURRENT_SESSION_FILTER"/>
|
||||||
|
@ -52,7 +52,7 @@ public class FilterOrderRegistrationTests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void putWhenPredefinedFilterThenDoesNotOverride() {
|
public void putWhenPredefinedFilterThenDoesNotOverride() {
|
||||||
int position = 200;
|
int position = 300;
|
||||||
Integer predefinedFilterOrderBefore = this.filterOrderRegistration.getOrder(ChannelProcessingFilter.class);
|
Integer predefinedFilterOrderBefore = this.filterOrderRegistration.getOrder(ChannelProcessingFilter.class);
|
||||||
this.filterOrderRegistration.put(MyFilter.class, position);
|
this.filterOrderRegistration.put(MyFilter.class, position);
|
||||||
Integer myFilterOrder = this.filterOrderRegistration.getOrder(MyFilter.class);
|
Integer myFilterOrder = this.filterOrderRegistration.getOrder(MyFilter.class);
|
||||||
|
@ -167,6 +167,7 @@ However, there are times that it is beneficial to know the ordering.
|
|||||||
|
|
||||||
The following is a comprehensive list of Spring Security Filter ordering:
|
The following is a comprehensive list of Spring Security Filter ordering:
|
||||||
|
|
||||||
|
* xref:servlet/authentication/session-management.adoc#session-mgmt-force-session-creation[`ForceEagerSessionCreationFilter`]
|
||||||
* `ChannelProcessingFilter`
|
* `ChannelProcessingFilter`
|
||||||
* `WebAsyncManagerIntegrationFilter`
|
* `WebAsyncManagerIntegrationFilter`
|
||||||
* `SecurityContextPersistenceFilter`
|
* `SecurityContextPersistenceFilter`
|
||||||
|
@ -3,6 +3,35 @@
|
|||||||
HTTP session-related functionality is handled by a combination of the {security-api-url}org/springframework/security/authentication/AuthenticationProvider.html[`SessionManagementFilter`] and the {security-api-url}org/springframework/security/web/authentication/session/SessionAuthenticationStrategy.html[`SessionAuthenticationStrategy`] interface, to which the filter delegates.
|
HTTP session-related functionality is handled by a combination of the {security-api-url}org/springframework/security/authentication/AuthenticationProvider.html[`SessionManagementFilter`] and the {security-api-url}org/springframework/security/web/authentication/session/SessionAuthenticationStrategy.html[`SessionAuthenticationStrategy`] interface, to which the filter delegates.
|
||||||
Typical usage includes session-fixation protection attack prevention, detection of session timeouts, and restrictions on how many sessions an authenticated user may have open concurrently.
|
Typical usage includes session-fixation protection attack prevention, detection of session timeouts, and restrictions on how many sessions an authenticated user may have open concurrently.
|
||||||
|
|
||||||
|
[[session-mgmt-force-session-creation]]
|
||||||
|
== Force Eager Session Creation
|
||||||
|
|
||||||
|
At times it can be valuable to eagerly create sessions.
|
||||||
|
This can be done by using the {security-api-url}org/springframework/security/web/session/ForceEagerSessionCreationFilter.html[`ForceEagerSessionCreationFilter`] which can be configured using:
|
||||||
|
|
||||||
|
====
|
||||||
|
.Java
|
||||||
|
[source,java,role="primary"]
|
||||||
|
----
|
||||||
|
@Bean
|
||||||
|
public SecurityFilterChain filterChain(HttpSecurity http) {
|
||||||
|
http
|
||||||
|
.sessionManagement(session -> session
|
||||||
|
.sessionCreationPolicy(SessionCreationPolicy.ALWAYS)
|
||||||
|
);
|
||||||
|
return http.build();
|
||||||
|
}
|
||||||
|
----
|
||||||
|
|
||||||
|
.XML
|
||||||
|
[source,xml,role="secondary"]
|
||||||
|
----
|
||||||
|
<http create-session="ALWAYS">
|
||||||
|
|
||||||
|
</http>
|
||||||
|
----
|
||||||
|
====
|
||||||
|
|
||||||
== Detecting Timeouts
|
== Detecting Timeouts
|
||||||
You can configure Spring Security to detect the submission of an invalid session ID and redirect the user to an appropriate URL.
|
You can configure Spring Security to detect the submission of an invalid session ID and redirect the user to an appropriate URL.
|
||||||
To do so, configure the `session-management` element:
|
To do so, configure the `session-management` element:
|
||||||
|
@ -274,6 +274,10 @@ The filters, aliases, and namespace elements and attributes that create the filt
|
|||||||
| `DisableEncodeUrlFilter`
|
| `DisableEncodeUrlFilter`
|
||||||
| `http@disable-url-rewriting`
|
| `http@disable-url-rewriting`
|
||||||
|
|
||||||
|
| FORCE_EAGER_SESSION_FILTER
|
||||||
|
| `ForceEagerSessionCreationFilter`
|
||||||
|
| `http@create-session="ALWAYS"`
|
||||||
|
|
||||||
| CHANNEL_FILTER
|
| CHANNEL_FILTER
|
||||||
| `ChannelProcessingFilter`
|
| `ChannelProcessingFilter`
|
||||||
| `http/intercept-url@requires-channel`
|
| `http/intercept-url@requires-channel`
|
||||||
|
@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
* 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.session;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import jakarta.servlet.FilterChain;
|
||||||
|
import jakarta.servlet.ServletException;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
import jakarta.servlet.http.HttpSession;
|
||||||
|
|
||||||
|
import org.springframework.core.log.LogMessage;
|
||||||
|
import org.springframework.web.filter.OncePerRequestFilter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Eagerly creates {@link HttpSession} if it does not already exist.
|
||||||
|
*
|
||||||
|
* @author Rob Winch
|
||||||
|
* @since 5.7
|
||||||
|
*/
|
||||||
|
public class ForceEagerSessionCreationFilter extends OncePerRequestFilter {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
|
||||||
|
throws ServletException, IOException {
|
||||||
|
HttpSession session = request.getSession();
|
||||||
|
if (this.logger.isDebugEnabled() && session.isNew()) {
|
||||||
|
this.logger.debug(LogMessage.format("Created session eagerly"));
|
||||||
|
}
|
||||||
|
filterChain.doFilter(request, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* 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.session;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import org.springframework.mock.web.MockFilterChain;
|
||||||
|
import org.springframework.mock.web.MockHttpServletRequest;
|
||||||
|
import org.springframework.mock.web.MockHttpServletResponse;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
class ForceEagerSessionCreationFilterTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void createsSession() throws Exception {
|
||||||
|
ForceEagerSessionCreationFilter filter = new ForceEagerSessionCreationFilter();
|
||||||
|
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||||
|
MockFilterChain chain = new MockFilterChain();
|
||||||
|
|
||||||
|
filter.doFilter(request, new MockHttpServletResponse(), chain);
|
||||||
|
|
||||||
|
assertThat(request.getSession(false)).isNotNull();
|
||||||
|
assertThat(chain.getRequest()).isEqualTo(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user