spring-session
spring-session copied to clipboard
Possibility to apply the `SessionRepositoryFilter` conditionally.
Expected Behavior
The SessionRepositoryFilter can be applied conditionally.
Current Behavior
The SessionRepositoryFilter cannot be applied conditionally.
Context
We are working on a legacy giant project and we want to migrate to Spring Session progressively. Currently, it seems like the SessionRepositoryFilter is applied to all requests once set up. However, we only want to apply the filter to some requests, for example, requests that have a specific header or requests that have a specific path.
I looked into the source code of SessionRepositoryFilter and it seems like there is no way to achieve this. I am wondering if there is a way to achieve this with the current Spring Session implementation.
If not possible, shall we consider introducing such a mechanism to the Spring Session? For example:
- Support accepting a customized
SessionRepositoryFilterbean, instead of creating a new one in SpringHttpSessionConfiguration.java - Support passing a condition bean to the
SessionRepositoryFilterbean, so that the filter can be applied conditionally. - Or any other better ideas?
Thanks in advance!
The current solution is to define our own SessionRepositoryFilter, which extends the default SessionRepositoryFilter and add condition check in the doFilterInternal method.
In the Spring configuration class, implement the BeanDefinitionRegistryPostProcessor and remove the default springSessionRepositoryFilter bean definition, then add a new bean definition with the bean class set to our own SessionRepositoryFilter.
ConditionalSessionRepositoryFilter.java
public class ConditionalSessionRepositoryFilter<S extends Session> extends SessionRepositoryFilter<S> {
public ConditionalSessionRepositoryFilter(SessionRepository<S> sessionRepository) {
super(sessionRepository);
}
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
if (shouldNotFilter(request)) {
filterChain.doFilter(request, response);
return;
}
super.doFilterInternal(request, response, filterChain);
}
private boolean shouldNotFilter(HttpServletRequest request) {
// Return true or false based on your needs.
}
}
SpringSessionConfig.java
@Configuration(proxyBeanMethods = false)
@EnableRedisIndexedHttpSession
public class SpringSessionConfig implements BeanDefinitionRegistryPostProcessor {
@Bean
public LettuceConnectionFactory connectionFactory() {
return new LettuceConnectionFactory();
}
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
registry.removeBeanDefinition("springSessionRepositoryFilter");
BeanDefinition definition = BeanDefinitionBuilder.genericBeanDefinition(ConditionalSessionRepositoryFilter.class)
.addConstructorArgReference("sessionRepository")
.getBeanDefinition();
registry.registerBeanDefinition("springSessionRepositoryFilter", definition);
}
}
Not sure whether it is possible for Spring Session to define an optional condition bean in SessionRepositoryFilter and make it injectable. If yes, we don't have to implement our own postProcessBeanDefinitionRegistry hook method.
Thanks for the report @yuezk. I agree that there should be an easier way to define my own SessionRepositoryFilter. Let's use this ticket to investigate if there is a better way to structure our configuration classes so we can have a better reuse if we want to customize some components that it creates.