Commit 02e836b7 authored by Andy Wilkinson's avatar Andy Wilkinson

Allow Session's repository filter to be configured via the environment

Closes gh-8301
parent 80e31e04
...@@ -16,9 +16,14 @@ ...@@ -16,9 +16,14 @@
package org.springframework.boot.autoconfigure.session; package org.springframework.boot.autoconfigure.session;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import org.springframework.beans.factory.ObjectProvider; import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.autoconfigure.web.ServerProperties; import org.springframework.boot.autoconfigure.web.ServerProperties;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.session.web.http.SessionRepositoryFilter;
/** /**
* Configuration properties for Spring Session. * Configuration properties for Spring Session.
...@@ -38,6 +43,8 @@ public class SessionProperties { ...@@ -38,6 +43,8 @@ public class SessionProperties {
private Integer timeout; private Integer timeout;
private Servlet servlet = new Servlet();
public SessionProperties(ObjectProvider<ServerProperties> serverProperties) { public SessionProperties(ObjectProvider<ServerProperties> serverProperties) {
ServerProperties properties = serverProperties.getIfUnique(); ServerProperties properties = serverProperties.getIfUnique();
this.timeout = (properties != null ? properties.getSession().getTimeout() : null); this.timeout = (properties != null ? properties.getSession().getTimeout() : null);
...@@ -60,4 +67,46 @@ public class SessionProperties { ...@@ -60,4 +67,46 @@ public class SessionProperties {
return this.timeout; return this.timeout;
} }
public Servlet getServlet() {
return this.servlet;
}
public void setServlet(Servlet servlet) {
this.servlet = servlet;
}
/**
* Servlet-related properties.
*/
public static class Servlet {
/**
* Session repository filter order.
*/
private int filterOrder = SessionRepositoryFilter.DEFAULT_ORDER;
/**
* Session repository filter dispatcher types.
*/
private Set<String> filterDispatcherTypes = new HashSet<>(
Arrays.asList("ASYNC", "ERROR", "REQUEST"));
public int getFilterOrder() {
return this.filterOrder;
}
public void setFilterOrder(int filterOrder) {
this.filterOrder = filterOrder;
}
public Set<String> getFilterDispatcherTypes() {
return this.filterDispatcherTypes;
}
public void setFilterDispatcherTypes(Set<String> filterDispatcherTypes) {
this.filterDispatcherTypes = filterDispatcherTypes;
}
}
} }
...@@ -17,10 +17,14 @@ ...@@ -17,10 +17,14 @@
package org.springframework.boot.autoconfigure.session; package org.springframework.boot.autoconfigure.session;
import java.util.EnumSet; import java.util.EnumSet;
import java.util.Locale;
import java.util.Set;
import java.util.stream.Collectors;
import javax.servlet.DispatcherType; import javax.servlet.DispatcherType;
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.web.servlet.FilterRegistrationBean; import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
...@@ -33,17 +37,30 @@ import org.springframework.session.web.http.SessionRepositoryFilter; ...@@ -33,17 +37,30 @@ import org.springframework.session.web.http.SessionRepositoryFilter;
*/ */
@Configuration @Configuration
@ConditionalOnBean(SessionRepositoryFilter.class) @ConditionalOnBean(SessionRepositoryFilter.class)
@EnableConfigurationProperties(SessionProperties.class)
class SessionRepositoryFilterConfiguration { class SessionRepositoryFilterConfiguration {
@Bean @Bean
public FilterRegistrationBean<SessionRepositoryFilter<?>> sessionRepositoryFilterRegistration( public FilterRegistrationBean<SessionRepositoryFilter<?>> sessionRepositoryFilterRegistration(
SessionRepositoryFilter<?> filter) { SessionProperties sessionProperties, SessionRepositoryFilter<?> filter) {
FilterRegistrationBean<SessionRepositoryFilter<?>> registration = new FilterRegistrationBean<>( FilterRegistrationBean<SessionRepositoryFilter<?>> registration = new FilterRegistrationBean<>(
filter); filter);
registration.setDispatcherTypes(EnumSet.of(DispatcherType.ASYNC, registration.setDispatcherTypes(getDispatcherTypes(sessionProperties));
DispatcherType.ERROR, DispatcherType.REQUEST)); registration.setOrder(sessionProperties.getServlet().getFilterOrder());
registration.setOrder(SessionRepositoryFilter.DEFAULT_ORDER);
return registration; return registration;
} }
private EnumSet<DispatcherType> getDispatcherTypes(
SessionProperties sessionProperties) {
Set<String> filterDispatcherTypes = sessionProperties.getServlet()
.getFilterDispatcherTypes();
if (filterDispatcherTypes == null) {
return null;
}
return filterDispatcherTypes.stream()
.map((type) -> type.toUpperCase(Locale.ENGLISH))
.map(DispatcherType::valueOf).collect(Collectors
.collectingAndThen(Collectors.toSet(), EnumSet::copyOf));
}
} }
...@@ -116,6 +116,27 @@ public class SessionAutoConfigurationTests extends AbstractSessionAutoConfigurat ...@@ -116,6 +116,27 @@ public class SessionAutoConfigurationTests extends AbstractSessionAutoConfigurat
DispatcherType.ERROR, DispatcherType.REQUEST); DispatcherType.ERROR, DispatcherType.REQUEST);
} }
@Test
public void filterOrderCanBeCustomized() {
load("spring.session.store-type=hash-map",
"spring.session.servlet.filter-order=123");
FilterRegistrationBean<?> registration = this.context
.getBean(FilterRegistrationBean.class);
assertThat(registration.getOrder()).isEqualTo(123);
}
@SuppressWarnings("unchecked")
@Test
public void filterDispatcherTypesCanBeCustomized() {
load("spring.session.store-type=hash-map",
"spring.session.servlet.filter-dispatcher-types=error, request");
FilterRegistrationBean<?> registration = this.context
.getBean(FilterRegistrationBean.class);
assertThat((EnumSet<DispatcherType>) ReflectionTestUtils.getField(registration,
"dispatcherTypes")).containsOnly(DispatcherType.ERROR,
DispatcherType.REQUEST);
}
@Configuration @Configuration
static class SessionRepositoryConfiguration { static class SessionRepositoryConfiguration {
......
...@@ -193,6 +193,8 @@ content into your application; rather pick only the properties that you need. ...@@ -193,6 +193,8 @@ content into your application; rather pick only the properties that you need.
server.session.cookie.path= # Path of the session cookie. server.session.cookie.path= # Path of the session cookie.
server.session.cookie.secure= # "Secure" flag for the session cookie. server.session.cookie.secure= # "Secure" flag for the session cookie.
server.session.persistent=false # Persist session data between restarts. server.session.persistent=false # Persist session data between restarts.
server.session.servlet.filter-order=-2147483598 # Session repository filter order.
server.session.servlet.filter-dispatcher-types=ASYNC, ERROR, REQUEST # Session repository filter dispatcher types.
server.session.store-dir= # Directory used to store session data. server.session.store-dir= # Directory used to store session data.
server.session.timeout= # Session timeout in seconds. server.session.timeout= # Session timeout in seconds.
server.session.tracking-modes= # Session tracking modes (one or more of the following: "cookie", "url", "ssl"). server.session.tracking-modes= # Session tracking modes (one or more of the following: "cookie", "url", "ssl").
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment