Skip to content

Allow to configure custom SessionRepositoryFilter #3408

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2014-2022 the original author or authors.
* Copyright 2014-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.
Expand All @@ -24,6 +24,7 @@
import org.springframework.session.SessionRepository;
import org.springframework.session.events.SessionCreatedEvent;
import org.springframework.session.events.SessionDestroyedEvent;
import org.springframework.session.web.http.SessionRepositoryFilter;

/**
* Add this annotation to an {@code @Configuration} class to expose the
Expand Down Expand Up @@ -67,6 +68,7 @@
* </ul>
*
* @author Rob Winch
* @author Yanming Zhou
* @since 1.1
*/
@Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
Expand All @@ -75,4 +77,11 @@
@Import(SpringHttpSessionConfiguration.class)
public @interface EnableSpringHttpSession {

/**
* Returns the {@link SessionRepositoryFilter} class to be used. Defaults to
* {@link SessionRepositoryFilter}.
* @return the {@link SessionRepositoryFilter} class
*/
Class<? extends SessionRepositoryFilter> sessionRepositoryFilterClass() default SessionRepositoryFilter.class;

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2014-2022 the original author or authors.
* Copyright 2014-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.
Expand All @@ -16,6 +16,7 @@

package org.springframework.session.config.annotation.web.http;

import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.List;

Expand All @@ -32,6 +33,9 @@
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportAware;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.session.Session;
import org.springframework.session.SessionRepository;
import org.springframework.session.events.SessionCreatedEvent;
Expand Down Expand Up @@ -86,11 +90,12 @@
*
* @author Rob Winch
* @author Vedran Pavic
* @author Yanming Zhou
* @since 1.1
* @see EnableSpringHttpSession
*/
@Configuration(proxyBeanMethods = false)
public class SpringHttpSessionConfiguration implements InitializingBean, ApplicationContextAware {
public class SpringHttpSessionConfiguration implements InitializingBean, ApplicationContextAware, ImportAware {

private final Log logger = LogFactory.getLog(getClass());

Expand All @@ -106,6 +111,18 @@ public class SpringHttpSessionConfiguration implements InitializingBean, Applica

private List<HttpSessionListener> httpSessionListeners = new ArrayList<>();

@SuppressWarnings("rawtypes")
private Class<? extends SessionRepositoryFilter> sessionRepositoryFilterClass = SessionRepositoryFilter.class;

@Override
public void setImportMetadata(AnnotationMetadata importMetadata) {
AnnotationAttributes annotationAttributes = AnnotationAttributes
.fromMap(importMetadata.getAnnotationAttributes(EnableSpringHttpSession.class.getName()));
if (annotationAttributes != null) {
this.sessionRepositoryFilterClass = annotationAttributes.getClass("sessionRepositoryFilterClass");
}
}

@Override
public void afterPropertiesSet() {
this.defaultHttpSessionIdResolver.setCookieSerializer(getCookieSerializer());
Expand All @@ -117,9 +134,20 @@ public SessionEventHttpSessionListenerAdapter sessionEventHttpSessionListenerAda
}

@Bean
@SuppressWarnings({ "unchecked", "rawtypes" })
public <S extends Session> SessionRepositoryFilter<? extends Session> springSessionRepositoryFilter(
SessionRepository<S> sessionRepository) {
SessionRepositoryFilter<S> sessionRepositoryFilter = new SessionRepositoryFilter<>(sessionRepository);
SessionRepositoryFilter<S> sessionRepositoryFilter;
try {
Constructor<? extends SessionRepositoryFilter> ctor = this.sessionRepositoryFilterClass
.getDeclaredConstructor(SessionRepository.class);
ctor.setAccessible(true);
sessionRepositoryFilter = ctor.newInstance(sessionRepository);
}
catch (Exception ex) {
throw new IllegalArgumentException("Please make sure class [" + this.sessionRepositoryFilterClass
+ "] has public constructor accepts SessionRepository parameter.", ex);
}
sessionRepositoryFilter.setHttpSessionIdResolver(this.httpSessionIdResolver);
return sessionRepositoryFilter;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2014-2019 the original author or authors.
* Copyright 2014-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.
Expand Down Expand Up @@ -31,6 +31,7 @@
import org.springframework.context.annotation.Configuration;
import org.springframework.mock.web.MockServletContext;
import org.springframework.session.MapSessionRepository;
import org.springframework.session.Session;
import org.springframework.session.SessionRepository;
import org.springframework.session.security.web.authentication.SpringSessionRememberMeServices;
import org.springframework.session.web.http.CookieHttpSessionIdResolver;
Expand All @@ -50,6 +51,7 @@
* Tests for {@link SpringHttpSessionConfiguration}.
*
* @author Vedran Pavic
* @author Yanming Zhou
*/
class SpringHttpSessionConfigurationTests {

Expand Down Expand Up @@ -130,6 +132,14 @@ void rememberMeServicesAndCustomDefaultCookieSerializerThenWarnIfRememberMeReque
}
}

@Test
void customizeSessionRepositoryFilter() {
registerAndRefresh(CustomSessionRepositoryFilterConfiguration.class);

SessionRepositoryFilter<?> sessionRepositoryFilter = this.context.getBean(SessionRepositoryFilter.class);
assertThat(sessionRepositoryFilter).isInstanceOf(MySessionRepositoryFilter.class);
}

@Configuration
@EnableSpringHttpSession
static class EmptyConfiguration {
Expand Down Expand Up @@ -189,4 +199,18 @@ DefaultCookieSerializer defaultCookieSerializer() {

}

@Configuration
@EnableSpringHttpSession(sessionRepositoryFilterClass = MySessionRepositoryFilter.class)
static class CustomSessionRepositoryFilterConfiguration extends BaseConfiguration {

}

public static class MySessionRepositoryFilter extends SessionRepositoryFilter<Session> {

MySessionRepositoryFilter(SessionRepository<Session> sessionRepository) {
super(sessionRepository);
}

}

}
Loading