commit
cd5f0dff21
|
@ -21,12 +21,14 @@ import java.util.stream.Collectors;
|
||||||
|
|
||||||
import jakarta.servlet.DispatcherType;
|
import jakarta.servlet.DispatcherType;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.ListableBeanFactory;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
import org.springframework.boot.web.servlet.DelegatingFilterProxyRegistrationBean;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.session.web.http.SessionRepositoryFilter;
|
import org.springframework.session.web.http.SessionRepositoryFilter;
|
||||||
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configuration for customizing the registration of the {@link SessionRepositoryFilter}.
|
* Configuration for customizing the registration of the {@link SessionRepositoryFilter}.
|
||||||
|
@ -39,9 +41,12 @@ import org.springframework.session.web.http.SessionRepositoryFilter;
|
||||||
class SessionRepositoryFilterConfiguration {
|
class SessionRepositoryFilterConfiguration {
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
FilterRegistrationBean<SessionRepositoryFilter<?>> sessionRepositoryFilterRegistration(
|
DelegatingFilterProxyRegistrationBean sessionRepositoryFilterRegistration(SessionProperties sessionProperties,
|
||||||
SessionProperties sessionProperties, SessionRepositoryFilter<?> filter) {
|
ListableBeanFactory beanFactory) {
|
||||||
FilterRegistrationBean<SessionRepositoryFilter<?>> registration = new FilterRegistrationBean<>(filter);
|
String[] targetBeanNames = beanFactory.getBeanNamesForType(SessionRepositoryFilter.class, false, false);
|
||||||
|
Assert.state(targetBeanNames.length == 1, "Expected single SessionRepositoryFilter bean");
|
||||||
|
DelegatingFilterProxyRegistrationBean registration = new DelegatingFilterProxyRegistrationBean(
|
||||||
|
targetBeanNames[0]);
|
||||||
registration.setDispatcherTypes(getDispatcherTypes(sessionProperties));
|
registration.setDispatcherTypes(getDispatcherTypes(sessionProperties));
|
||||||
registration.setOrder(sessionProperties.getServlet().getFilterOrder());
|
registration.setOrder(sessionProperties.getServlet().getFilterOrder());
|
||||||
return registration;
|
return registration;
|
||||||
|
|
|
@ -0,0 +1,66 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2012-2023 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.boot.autoconfigure.session;
|
||||||
|
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
|
||||||
|
import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration;
|
||||||
|
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
|
||||||
|
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext;
|
||||||
|
import org.springframework.context.ConfigurableApplicationContext;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.session.MapSessionRepository;
|
||||||
|
import org.springframework.session.config.annotation.web.http.EnableSpringHttpSession;
|
||||||
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Integration tests to ensure {@link SessionAutoConfiguration} and
|
||||||
|
* {@link SessionRepositoryFilterConfiguration} does not cause early initialization.
|
||||||
|
*
|
||||||
|
* @author Phillip Webb
|
||||||
|
*/
|
||||||
|
public class SessionAutoConfigurationEarlyInitializationIntegrationTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void configurationIsFrozenWhenSessionRepositoryAccessed() {
|
||||||
|
new WebApplicationContextRunner(AnnotationConfigServletWebServerApplicationContext::new)
|
||||||
|
.withSystemProperties("spring.jndi.ignore=true")
|
||||||
|
.withPropertyValues("server.port=0")
|
||||||
|
.withUserConfiguration(TestConfiguration.class)
|
||||||
|
.run((context) -> assertThat(context).hasSingleBean(MapSessionRepository.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Configuration(proxyBeanMethods = false)
|
||||||
|
@EnableSpringHttpSession
|
||||||
|
@ImportAutoConfiguration({ ServletWebServerFactoryAutoConfiguration.class, SessionAutoConfiguration.class })
|
||||||
|
static class TestConfiguration {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
MapSessionRepository mapSessionRepository(ConfigurableApplicationContext context) {
|
||||||
|
Assert.isTrue(context.getBeanFactory().isConfigurationFrozen(), "Context should be frozen");
|
||||||
|
return new MapSessionRepository(new LinkedHashMap<>());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -37,7 +37,7 @@ import org.springframework.boot.sql.init.DatabaseInitializationSettings;
|
||||||
import org.springframework.boot.test.context.FilteredClassLoader;
|
import org.springframework.boot.test.context.FilteredClassLoader;
|
||||||
import org.springframework.boot.test.context.assertj.AssertableWebApplicationContext;
|
import org.springframework.boot.test.context.assertj.AssertableWebApplicationContext;
|
||||||
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
|
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
|
||||||
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
import org.springframework.boot.web.servlet.AbstractFilterRegistrationBean;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.context.annotation.Primary;
|
import org.springframework.context.annotation.Primary;
|
||||||
|
@ -97,7 +97,7 @@ class SessionAutoConfigurationJdbcTests extends AbstractSessionAutoConfiguration
|
||||||
@Test
|
@Test
|
||||||
void filterOrderCanBeCustomized() {
|
void filterOrderCanBeCustomized() {
|
||||||
this.contextRunner.withPropertyValues("spring.session.servlet.filter-order=123").run((context) -> {
|
this.contextRunner.withPropertyValues("spring.session.servlet.filter-order=123").run((context) -> {
|
||||||
FilterRegistrationBean<?> registration = context.getBean(FilterRegistrationBean.class);
|
AbstractFilterRegistrationBean<?> registration = context.getBean(AbstractFilterRegistrationBean.class);
|
||||||
assertThat(registration.getOrder()).isEqualTo(123);
|
assertThat(registration.getOrder()).isEqualTo(123);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,7 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties
|
||||||
import org.springframework.boot.test.context.FilteredClassLoader;
|
import org.springframework.boot.test.context.FilteredClassLoader;
|
||||||
import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner;
|
import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner;
|
||||||
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
|
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
|
||||||
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
import org.springframework.boot.web.servlet.AbstractFilterRegistrationBean;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.core.annotation.Order;
|
import org.springframework.core.annotation.Order;
|
||||||
|
@ -48,6 +48,7 @@ import org.springframework.session.web.http.DefaultCookieSerializer;
|
||||||
import org.springframework.session.web.http.HeaderHttpSessionIdResolver;
|
import org.springframework.session.web.http.HeaderHttpSessionIdResolver;
|
||||||
import org.springframework.session.web.http.HttpSessionIdResolver;
|
import org.springframework.session.web.http.HttpSessionIdResolver;
|
||||||
import org.springframework.session.web.http.SessionRepositoryFilter;
|
import org.springframework.session.web.http.SessionRepositoryFilter;
|
||||||
|
import org.springframework.web.filter.DelegatingFilterProxy;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
@ -98,8 +99,16 @@ class SessionAutoConfigurationTests extends AbstractSessionAutoConfigurationTest
|
||||||
@Test
|
@Test
|
||||||
void filterIsRegisteredWithAsyncErrorAndRequestDispatcherTypes() {
|
void filterIsRegisteredWithAsyncErrorAndRequestDispatcherTypes() {
|
||||||
this.contextRunner.withUserConfiguration(SessionRepositoryConfiguration.class).run((context) -> {
|
this.contextRunner.withUserConfiguration(SessionRepositoryConfiguration.class).run((context) -> {
|
||||||
FilterRegistrationBean<?> registration = context.getBean(FilterRegistrationBean.class);
|
AbstractFilterRegistrationBean<?> registration = context.getBean(AbstractFilterRegistrationBean.class);
|
||||||
assertThat(registration.getFilter()).isSameAs(context.getBean(SessionRepositoryFilter.class));
|
DelegatingFilterProxy delegatingFilterProxy = (DelegatingFilterProxy) registration.getFilter();
|
||||||
|
try {
|
||||||
|
// Trigger actual initialization
|
||||||
|
delegatingFilterProxy.doFilter(null, null, null);
|
||||||
|
}
|
||||||
|
catch (Exception ex) {
|
||||||
|
}
|
||||||
|
assertThat(delegatingFilterProxy).extracting("delegate")
|
||||||
|
.isSameAs(context.getBean(SessionRepositoryFilter.class));
|
||||||
assertThat(registration)
|
assertThat(registration)
|
||||||
.extracting("dispatcherTypes", InstanceOfAssertFactories.iterable(DispatcherType.class))
|
.extracting("dispatcherTypes", InstanceOfAssertFactories.iterable(DispatcherType.class))
|
||||||
.containsOnly(DispatcherType.ASYNC, DispatcherType.ERROR, DispatcherType.REQUEST);
|
.containsOnly(DispatcherType.ASYNC, DispatcherType.ERROR, DispatcherType.REQUEST);
|
||||||
|
@ -111,7 +120,7 @@ class SessionAutoConfigurationTests extends AbstractSessionAutoConfigurationTest
|
||||||
this.contextRunner.withUserConfiguration(SessionRepositoryConfiguration.class)
|
this.contextRunner.withUserConfiguration(SessionRepositoryConfiguration.class)
|
||||||
.withPropertyValues("spring.session.servlet.filter-order=123")
|
.withPropertyValues("spring.session.servlet.filter-order=123")
|
||||||
.run((context) -> {
|
.run((context) -> {
|
||||||
FilterRegistrationBean<?> registration = context.getBean(FilterRegistrationBean.class);
|
AbstractFilterRegistrationBean<?> registration = context.getBean(AbstractFilterRegistrationBean.class);
|
||||||
assertThat(registration.getOrder()).isEqualTo(123);
|
assertThat(registration.getOrder()).isEqualTo(123);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -121,7 +130,7 @@ class SessionAutoConfigurationTests extends AbstractSessionAutoConfigurationTest
|
||||||
this.contextRunner.withUserConfiguration(SessionRepositoryConfiguration.class)
|
this.contextRunner.withUserConfiguration(SessionRepositoryConfiguration.class)
|
||||||
.withPropertyValues("spring.session.servlet.filter-dispatcher-types=error, request")
|
.withPropertyValues("spring.session.servlet.filter-dispatcher-types=error, request")
|
||||||
.run((context) -> {
|
.run((context) -> {
|
||||||
FilterRegistrationBean<?> registration = context.getBean(FilterRegistrationBean.class);
|
AbstractFilterRegistrationBean<?> registration = context.getBean(AbstractFilterRegistrationBean.class);
|
||||||
assertThat(registration)
|
assertThat(registration)
|
||||||
.extracting("dispatcherTypes", InstanceOfAssertFactories.iterable(DispatcherType.class))
|
.extracting("dispatcherTypes", InstanceOfAssertFactories.iterable(DispatcherType.class))
|
||||||
.containsOnly(DispatcherType.ERROR, DispatcherType.REQUEST);
|
.containsOnly(DispatcherType.ERROR, DispatcherType.REQUEST);
|
||||||
|
@ -133,7 +142,7 @@ class SessionAutoConfigurationTests extends AbstractSessionAutoConfigurationTest
|
||||||
this.contextRunner.withUserConfiguration(SessionRepositoryConfiguration.class)
|
this.contextRunner.withUserConfiguration(SessionRepositoryConfiguration.class)
|
||||||
.withPropertyValues("spring.session.servlet.filter-dispatcher-types=")
|
.withPropertyValues("spring.session.servlet.filter-dispatcher-types=")
|
||||||
.run((context) -> {
|
.run((context) -> {
|
||||||
FilterRegistrationBean<?> registration = context.getBean(FilterRegistrationBean.class);
|
AbstractFilterRegistrationBean<?> registration = context.getBean(AbstractFilterRegistrationBean.class);
|
||||||
assertThat(registration)
|
assertThat(registration)
|
||||||
.extracting("dispatcherTypes", InstanceOfAssertFactories.iterable(DispatcherType.class))
|
.extracting("dispatcherTypes", InstanceOfAssertFactories.iterable(DispatcherType.class))
|
||||||
.isEmpty();
|
.isEmpty();
|
||||||
|
|
|
@ -16,8 +16,6 @@
|
||||||
|
|
||||||
package org.springframework.boot.autoconfigure.web.servlet;
|
package org.springframework.boot.autoconfigure.web.servlet;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
@ -42,7 +40,7 @@ import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||||
import org.springframework.security.web.FilterChainProxy;
|
import org.springframework.security.web.FilterChainProxy;
|
||||||
import org.springframework.session.MapSessionRepository;
|
import org.springframework.session.MapSessionRepository;
|
||||||
import org.springframework.session.config.annotation.web.http.EnableSpringHttpSession;
|
import org.springframework.session.config.annotation.web.http.EnableSpringHttpSession;
|
||||||
import org.springframework.session.web.http.SessionRepositoryFilter;
|
import org.springframework.web.filter.DelegatingFilterProxy;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.mockito.BDDMockito.given;
|
import static org.mockito.BDDMockito.given;
|
||||||
|
@ -71,17 +69,18 @@ class FilterOrderingIntegrationTests {
|
||||||
List<RegisteredFilter> registeredFilters = this.context.getBean(MockServletWebServerFactory.class)
|
List<RegisteredFilter> registeredFilters = this.context.getBean(MockServletWebServerFactory.class)
|
||||||
.getWebServer()
|
.getWebServer()
|
||||||
.getRegisteredFilters();
|
.getRegisteredFilters();
|
||||||
List<Filter> filters = new ArrayList<>(registeredFilters.size());
|
assertThat(registeredFilters.get(0).getFilter()).isInstanceOf(OrderedCharacterEncodingFilter.class);
|
||||||
for (RegisteredFilter registeredFilter : registeredFilters) {
|
assertThat(registeredFilters.get(1).getFilter()).isInstanceOf(DelegatingFilterProxy.class)
|
||||||
filters.add(registeredFilter.getFilter());
|
.extracting("targetBeanName")
|
||||||
}
|
.isEqualTo("springSessionRepositoryFilter");
|
||||||
Iterator<Filter> iterator = filters.iterator();
|
assertThat(registeredFilters.get(2).getFilter()).isInstanceOf(Filter.class)
|
||||||
assertThat(iterator.next()).isInstanceOf(OrderedCharacterEncodingFilter.class);
|
.extracting("beanName")
|
||||||
assertThat(iterator.next()).isInstanceOf(SessionRepositoryFilter.class);
|
.isEqualTo("hiddenHttpMethodFilter");
|
||||||
assertThat(iterator.next()).isInstanceOf(Filter.class);
|
assertThat(registeredFilters.get(3).getFilter()).isInstanceOf(Filter.class)
|
||||||
assertThat(iterator.next()).isInstanceOf(Filter.class);
|
.extracting("beanName")
|
||||||
assertThat(iterator.next()).isInstanceOf(OrderedRequestContextFilter.class);
|
.isEqualTo("formContentFilter");
|
||||||
assertThat(iterator.next()).isInstanceOf(FilterChainProxy.class);
|
assertThat(registeredFilters.get(4).getFilter()).isInstanceOf(OrderedRequestContextFilter.class);
|
||||||
|
assertThat(registeredFilters.get(6).getFilter()).isInstanceOf(FilterChainProxy.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void load() {
|
private void load() {
|
||||||
|
|
Loading…
Reference in New Issue