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 @@
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.boot.autoconfigure.web.ServerProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.session.web.http.SessionRepositoryFilter;
/**
* Configuration properties for Spring Session.
......@@ -38,6 +43,8 @@ public class SessionProperties {
private Integer timeout;
private Servlet servlet = new Servlet();
public SessionProperties(ObjectProvider<ServerProperties> serverProperties) {
ServerProperties properties = serverProperties.getIfUnique();
this.timeout = (properties != null ? properties.getSession().getTimeout() : null);
......@@ -60,4 +67,46 @@ public class SessionProperties {
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 @@
package org.springframework.boot.autoconfigure.session;
import java.util.EnumSet;
import java.util.Locale;
import java.util.Set;
import java.util.stream.Collectors;
import javax.servlet.DispatcherType;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
......@@ -33,17 +37,30 @@ import org.springframework.session.web.http.SessionRepositoryFilter;
*/
@Configuration
@ConditionalOnBean(SessionRepositoryFilter.class)
@EnableConfigurationProperties(SessionProperties.class)
class SessionRepositoryFilterConfiguration {
@Bean
public FilterRegistrationBean<SessionRepositoryFilter<?>> sessionRepositoryFilterRegistration(
SessionRepositoryFilter<?> filter) {
SessionProperties sessionProperties, SessionRepositoryFilter<?> filter) {
FilterRegistrationBean<SessionRepositoryFilter<?>> registration = new FilterRegistrationBean<>(
filter);
registration.setDispatcherTypes(EnumSet.of(DispatcherType.ASYNC,
DispatcherType.ERROR, DispatcherType.REQUEST));
registration.setOrder(SessionRepositoryFilter.DEFAULT_ORDER);
registration.setDispatcherTypes(getDispatcherTypes(sessionProperties));
registration.setOrder(sessionProperties.getServlet().getFilterOrder());
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
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
static class SessionRepositoryConfiguration {
......
......@@ -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.secure= # "Secure" flag for the session cookie.
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.timeout= # Session timeout in seconds.
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