Merge branch '3.0.x'

Closes gh-35242
pull/35256/head
Phillip Webb 2 years ago
commit cd5f0dff21

@ -21,12 +21,14 @@ import java.util.stream.Collectors;
import jakarta.servlet.DispatcherType;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
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.Configuration;
import org.springframework.session.web.http.SessionRepositoryFilter;
import org.springframework.util.Assert;
/**
* Configuration for customizing the registration of the {@link SessionRepositoryFilter}.
@ -39,9 +41,12 @@ import org.springframework.session.web.http.SessionRepositoryFilter;
class SessionRepositoryFilterConfiguration {
@Bean
FilterRegistrationBean<SessionRepositoryFilter<?>> sessionRepositoryFilterRegistration(
SessionProperties sessionProperties, SessionRepositoryFilter<?> filter) {
FilterRegistrationBean<SessionRepositoryFilter<?>> registration = new FilterRegistrationBean<>(filter);
DelegatingFilterProxyRegistrationBean sessionRepositoryFilterRegistration(SessionProperties sessionProperties,
ListableBeanFactory beanFactory) {
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.setOrder(sessionProperties.getServlet().getFilterOrder());
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.assertj.AssertableWebApplicationContext;
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.Configuration;
import org.springframework.context.annotation.Primary;
@ -97,7 +97,7 @@ class SessionAutoConfigurationJdbcTests extends AbstractSessionAutoConfiguration
@Test
void filterOrderCanBeCustomized() {
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);
});
}

@ -29,7 +29,7 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties
import org.springframework.boot.test.context.FilteredClassLoader;
import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner;
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.Configuration;
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.HttpSessionIdResolver;
import org.springframework.session.web.http.SessionRepositoryFilter;
import org.springframework.web.filter.DelegatingFilterProxy;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
@ -98,8 +99,16 @@ class SessionAutoConfigurationTests extends AbstractSessionAutoConfigurationTest
@Test
void filterIsRegisteredWithAsyncErrorAndRequestDispatcherTypes() {
this.contextRunner.withUserConfiguration(SessionRepositoryConfiguration.class).run((context) -> {
FilterRegistrationBean<?> registration = context.getBean(FilterRegistrationBean.class);
assertThat(registration.getFilter()).isSameAs(context.getBean(SessionRepositoryFilter.class));
AbstractFilterRegistrationBean<?> registration = context.getBean(AbstractFilterRegistrationBean.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)
.extracting("dispatcherTypes", InstanceOfAssertFactories.iterable(DispatcherType.class))
.containsOnly(DispatcherType.ASYNC, DispatcherType.ERROR, DispatcherType.REQUEST);
@ -111,7 +120,7 @@ class SessionAutoConfigurationTests extends AbstractSessionAutoConfigurationTest
this.contextRunner.withUserConfiguration(SessionRepositoryConfiguration.class)
.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);
});
}
@ -121,7 +130,7 @@ class SessionAutoConfigurationTests extends AbstractSessionAutoConfigurationTest
this.contextRunner.withUserConfiguration(SessionRepositoryConfiguration.class)
.withPropertyValues("spring.session.servlet.filter-dispatcher-types=error, request")
.run((context) -> {
FilterRegistrationBean<?> registration = context.getBean(FilterRegistrationBean.class);
AbstractFilterRegistrationBean<?> registration = context.getBean(AbstractFilterRegistrationBean.class);
assertThat(registration)
.extracting("dispatcherTypes", InstanceOfAssertFactories.iterable(DispatcherType.class))
.containsOnly(DispatcherType.ERROR, DispatcherType.REQUEST);
@ -133,7 +142,7 @@ class SessionAutoConfigurationTests extends AbstractSessionAutoConfigurationTest
this.contextRunner.withUserConfiguration(SessionRepositoryConfiguration.class)
.withPropertyValues("spring.session.servlet.filter-dispatcher-types=")
.run((context) -> {
FilterRegistrationBean<?> registration = context.getBean(FilterRegistrationBean.class);
AbstractFilterRegistrationBean<?> registration = context.getBean(AbstractFilterRegistrationBean.class);
assertThat(registration)
.extracting("dispatcherTypes", InstanceOfAssertFactories.iterable(DispatcherType.class))
.isEmpty();

@ -16,8 +16,6 @@
package org.springframework.boot.autoconfigure.web.servlet;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
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.session.MapSessionRepository;
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.mockito.BDDMockito.given;
@ -71,17 +69,18 @@ class FilterOrderingIntegrationTests {
List<RegisteredFilter> registeredFilters = this.context.getBean(MockServletWebServerFactory.class)
.getWebServer()
.getRegisteredFilters();
List<Filter> filters = new ArrayList<>(registeredFilters.size());
for (RegisteredFilter registeredFilter : registeredFilters) {
filters.add(registeredFilter.getFilter());
}
Iterator<Filter> iterator = filters.iterator();
assertThat(iterator.next()).isInstanceOf(OrderedCharacterEncodingFilter.class);
assertThat(iterator.next()).isInstanceOf(SessionRepositoryFilter.class);
assertThat(iterator.next()).isInstanceOf(Filter.class);
assertThat(iterator.next()).isInstanceOf(Filter.class);
assertThat(iterator.next()).isInstanceOf(OrderedRequestContextFilter.class);
assertThat(iterator.next()).isInstanceOf(FilterChainProxy.class);
assertThat(registeredFilters.get(0).getFilter()).isInstanceOf(OrderedCharacterEncodingFilter.class);
assertThat(registeredFilters.get(1).getFilter()).isInstanceOf(DelegatingFilterProxy.class)
.extracting("targetBeanName")
.isEqualTo("springSessionRepositoryFilter");
assertThat(registeredFilters.get(2).getFilter()).isInstanceOf(Filter.class)
.extracting("beanName")
.isEqualTo("hiddenHttpMethodFilter");
assertThat(registeredFilters.get(3).getFilter()).isInstanceOf(Filter.class)
.extracting("beanName")
.isEqualTo("formContentFilter");
assertThat(registeredFilters.get(4).getFilter()).isInstanceOf(OrderedRequestContextFilter.class);
assertThat(registeredFilters.get(6).getFilter()).isInstanceOf(FilterChainProxy.class);
}
private void load() {

Loading…
Cancel
Save