Create spring-boot-session modules
This commit is contained in:
committed by
Phillip Webb
parent
014240d576
commit
e288c81b7b
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2012-2020 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.session.autoconfigure;
|
||||
|
||||
import org.springframework.session.web.http.DefaultCookieSerializer;
|
||||
|
||||
/**
|
||||
* Callback interface that can be implemented by beans wishing to customize the
|
||||
* {@link DefaultCookieSerializer} configuration.
|
||||
*
|
||||
* @author Vedran Pavic
|
||||
* @since 4.0.0
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface DefaultCookieSerializerCustomizer {
|
||||
|
||||
/**
|
||||
* Customize the cookie serializer.
|
||||
* @param cookieSerializer the {@code DefaultCookieSerializer} to customize
|
||||
*/
|
||||
void customize(DefaultCookieSerializer cookieSerializer);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* Copyright 2012-2025 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.session.autoconfigure;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.AnyNestedCondition;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type;
|
||||
import org.springframework.boot.autoconfigure.web.ServerProperties;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.boot.context.properties.PropertyMapper;
|
||||
import org.springframework.boot.web.server.Cookie;
|
||||
import org.springframework.boot.web.server.Cookie.SameSite;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Conditional;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.security.web.authentication.RememberMeServices;
|
||||
import org.springframework.session.Session;
|
||||
import org.springframework.session.security.web.authentication.SpringSessionRememberMeServices;
|
||||
import org.springframework.session.web.http.CookieHttpSessionIdResolver;
|
||||
import org.springframework.session.web.http.CookieSerializer;
|
||||
import org.springframework.session.web.http.DefaultCookieSerializer;
|
||||
import org.springframework.session.web.http.HttpSessionIdResolver;
|
||||
|
||||
/**
|
||||
* {@link EnableAutoConfiguration Auto-configuration} for Spring Session.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
* @author Tommy Ludwig
|
||||
* @author Eddú Meléndez
|
||||
* @author Stephane Nicoll
|
||||
* @author Vedran Pavic
|
||||
* @author Weix Sun
|
||||
* @since 4.0.0
|
||||
*/
|
||||
@AutoConfiguration
|
||||
@ConditionalOnClass(Session.class)
|
||||
@ConditionalOnWebApplication
|
||||
@EnableConfigurationProperties({ ServerProperties.class, SessionProperties.class })
|
||||
public class SessionAutoConfiguration {
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnWebApplication(type = Type.SERVLET)
|
||||
@Import(SessionRepositoryFilterConfiguration.class)
|
||||
static class ServletSessionConfiguration {
|
||||
|
||||
@Bean
|
||||
@Conditional(DefaultCookieSerializerCondition.class)
|
||||
DefaultCookieSerializer cookieSerializer(ServerProperties serverProperties,
|
||||
ObjectProvider<DefaultCookieSerializerCustomizer> cookieSerializerCustomizers) {
|
||||
Cookie cookie = serverProperties.getServlet().getSession().getCookie();
|
||||
DefaultCookieSerializer cookieSerializer = new DefaultCookieSerializer();
|
||||
PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull();
|
||||
map.from(cookie::getName).to(cookieSerializer::setCookieName);
|
||||
map.from(cookie::getDomain).to(cookieSerializer::setDomainName);
|
||||
map.from(cookie::getPath).to(cookieSerializer::setCookiePath);
|
||||
map.from(cookie::getHttpOnly).to(cookieSerializer::setUseHttpOnlyCookie);
|
||||
map.from(cookie::getSecure).to(cookieSerializer::setUseSecureCookie);
|
||||
map.from(cookie::getMaxAge).asInt(Duration::getSeconds).to(cookieSerializer::setCookieMaxAge);
|
||||
map.from(cookie::getSameSite).as(SameSite::attributeValue).to(cookieSerializer::setSameSite);
|
||||
map.from(cookie::getPartitioned).to(cookieSerializer::setPartitioned);
|
||||
cookieSerializerCustomizers.orderedStream().forEach((customizer) -> customizer.customize(cookieSerializer));
|
||||
return cookieSerializer;
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnClass(RememberMeServices.class)
|
||||
static class RememberMeServicesConfiguration {
|
||||
|
||||
@Bean
|
||||
DefaultCookieSerializerCustomizer rememberMeServicesCookieSerializerCustomizer() {
|
||||
return (cookieSerializer) -> cookieSerializer
|
||||
.setRememberMeRequestAttribute(SpringSessionRememberMeServices.REMEMBER_ME_LOGIN_ATTR);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Condition to trigger the creation of a {@link DefaultCookieSerializer}. This kicks
|
||||
* in if either no {@link HttpSessionIdResolver} and {@link CookieSerializer} beans
|
||||
* are registered, or if {@link CookieHttpSessionIdResolver} is registered but
|
||||
* {@link CookieSerializer} is not.
|
||||
*/
|
||||
static class DefaultCookieSerializerCondition extends AnyNestedCondition {
|
||||
|
||||
DefaultCookieSerializerCondition() {
|
||||
super(ConfigurationPhase.REGISTER_BEAN);
|
||||
}
|
||||
|
||||
@ConditionalOnMissingBean({ HttpSessionIdResolver.class, CookieSerializer.class })
|
||||
static class NoComponentsAvailable {
|
||||
|
||||
}
|
||||
|
||||
@ConditionalOnBean(CookieHttpSessionIdResolver.class)
|
||||
@ConditionalOnMissingBean(CookieSerializer.class)
|
||||
static class CookieHttpSessionIdResolverAvailable {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright 2012-2025 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.session.autoconfigure;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.boot.convert.DurationUnit;
|
||||
import org.springframework.boot.web.servlet.DispatcherType;
|
||||
import org.springframework.session.web.http.SessionRepositoryFilter;
|
||||
|
||||
/**
|
||||
* Configuration properties for Spring Session.
|
||||
*
|
||||
* @author Tommy Ludwig
|
||||
* @author Stephane Nicoll
|
||||
* @author Vedran Pavic
|
||||
* @since 4.0.0
|
||||
*/
|
||||
@ConfigurationProperties("spring.session")
|
||||
public class SessionProperties {
|
||||
|
||||
/**
|
||||
* Session timeout. If a duration suffix is not specified, seconds will be used.
|
||||
*/
|
||||
@DurationUnit(ChronoUnit.SECONDS)
|
||||
private Duration timeout;
|
||||
|
||||
private Servlet servlet = new Servlet();
|
||||
|
||||
public Duration getTimeout() {
|
||||
return this.timeout;
|
||||
}
|
||||
|
||||
public void setTimeout(Duration timeout) {
|
||||
this.timeout = timeout;
|
||||
}
|
||||
|
||||
public Servlet getServlet() {
|
||||
return this.servlet;
|
||||
}
|
||||
|
||||
public void setServlet(Servlet servlet) {
|
||||
this.servlet = servlet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the session timeout. If no timeout is configured, the
|
||||
* {@code fallbackTimeout} is used.
|
||||
* @param fallbackTimeout a fallback timeout value if the timeout isn't configured
|
||||
* @return the session timeout
|
||||
*/
|
||||
public Duration determineTimeout(Supplier<Duration> fallbackTimeout) {
|
||||
return (this.timeout != null) ? this.timeout : fallbackTimeout.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Servlet-related properties.
|
||||
*/
|
||||
public static class Servlet {
|
||||
|
||||
/**
|
||||
* Session repository filter order.
|
||||
*/
|
||||
private int filterOrder = SessionRepositoryFilter.DEFAULT_ORDER;
|
||||
|
||||
/**
|
||||
* Session repository filter dispatcher types.
|
||||
*/
|
||||
private Set<DispatcherType> filterDispatcherTypes = new HashSet<>(
|
||||
Arrays.asList(DispatcherType.ASYNC, DispatcherType.ERROR, DispatcherType.REQUEST));
|
||||
|
||||
public int getFilterOrder() {
|
||||
return this.filterOrder;
|
||||
}
|
||||
|
||||
public void setFilterOrder(int filterOrder) {
|
||||
this.filterOrder = filterOrder;
|
||||
}
|
||||
|
||||
public Set<DispatcherType> getFilterDispatcherTypes() {
|
||||
return this.filterDispatcherTypes;
|
||||
}
|
||||
|
||||
public void setFilterDispatcherTypes(Set<DispatcherType> filterDispatcherTypes) {
|
||||
this.filterDispatcherTypes = filterDispatcherTypes;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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.session.autoconfigure;
|
||||
|
||||
import java.util.EnumSet;
|
||||
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.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}.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnBean(SessionRepositoryFilter.class)
|
||||
@EnableConfigurationProperties(SessionProperties.class)
|
||||
class SessionRepositoryFilterConfiguration {
|
||||
|
||||
@Bean
|
||||
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;
|
||||
}
|
||||
|
||||
private EnumSet<DispatcherType> getDispatcherTypes(SessionProperties sessionProperties) {
|
||||
SessionProperties.Servlet servletProperties = sessionProperties.getServlet();
|
||||
if (servletProperties.getFilterDispatcherTypes() == null) {
|
||||
return null;
|
||||
}
|
||||
return servletProperties.getFilterDispatcherTypes()
|
||||
.stream()
|
||||
.map((type) -> DispatcherType.valueOf(type.name()))
|
||||
.collect(Collectors.toCollection(() -> EnumSet.noneOf(DispatcherType.class)));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright 2012-2019 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Auto-configuration for Spring Session.
|
||||
*/
|
||||
package org.springframework.boot.session.autoconfigure;
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"properties": [
|
||||
{
|
||||
"name": "spring.session.servlet.filter-dispatcher-types",
|
||||
"defaultValue": [
|
||||
"async",
|
||||
"error",
|
||||
"request"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
org.springframework.boot.session.autoconfigure.SessionAutoConfiguration
|
||||
Reference in New Issue
Block a user