I'm trying to share the HTTP session between a Spring MVC (Servlet-based) application and a Spring WebFlux application using Spring Session backed by Redis. What I'm trying to achieve:
A user authenticates via Spring Security in the MVC app. I want the WebFlux app to read the same session stored in Redis and access the authenticated user's context from SPRING_SECURITY_CONTEXT.
That is, the SecurityContext should be available in both applications transparently, so that authentication state is consistent.
The issue:
When the session is created on the MVC (Servlet) side, the WebFlux application:
- Receives the correct session ID via cookie.
- But either creates a new session in Redis or cannot deserialize the existing one.
- As a result,
SPRING_SECURITY_CONTEXTis missing in theMono<WebSession>when debugging the WebFlux security filter chain.
What I've tried:
Both applications are using the same Redis instance and the same namespace (spring:session)
Serialization is set to use
GenericJackson2JsonRedisSerializeron both sides.I configured
RedisIndexedSessionRepositoryon the Servlet app andReactiveRedisIndexedSessionRepositoryon the WebFlux app.I confirmed that the same cookie name (SESSION) is used and the session ID is shared between both apps.
Servlet (MVC):
@Bean
public RedisIndexedSessionRepository redisIndexedSessionRepository(RedisTemplate<String, Object> redisTemplate) {
redisTemplate.setDefaultSerializer(new GenericJackson2JsonRedisSerializer());
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
redisTemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
redisTemplate.afterPropertiesSet();
RedisIndexedSessionRepository repository = new RedisIndexedSessionRepository(redisTemplate);
repository.setDefaultMaxInactiveInterval(300);
repository.setRedisKeyNamespace("spring:session");
return repository;
}
WebFlux:
@Bean
@Primary
public ReactiveRedisIndexedSessionRepository reactiveRedisSessionRepository(ReactiveRedisConnectionFactory factory) {
RedisSerializationContext<String, Object> context = RedisSerializationContext
.<String, Object>newSerializationContext()
.key(new StringRedisSerializer())
.value(new GenericJackson2JsonRedisSerializer())
.hashKey(new StringRedisSerializer())
.hashValue(new GenericJackson2JsonRedisSerializer())
.build();
ReactiveRedisOperations<String, Object> operations = new ReactiveRedisTemplate<>(factory, context);
ReactiveRedisTemplate<String, String> indexTemplate = new ReactiveRedisTemplate<>(factory,
RedisSerializationContext.<String, String>newSerializationContext()
.key(new StringRedisSerializer())
.value(new StringRedisSerializer())
.hashKey(new StringRedisSerializer())
.hashValue(new StringRedisSerializer())
.build());
return new ReactiveRedisIndexedSessionRepository(operations, indexTemplate);
}
application.yml
spring:
session:
store-type: redis
redis:
namespace: spring:session
Questions:
- What might cause
SPRING_SECURITY_CONTEXTto be missing when reading the session from the WebFlux side? - Is sharing a session between Servlet and WebFlux apps officially supported? Are there any known limitations?
- Do I need to manually customize the deserialization of
SPRING_SECURITY_CONTEXTfor WebFlux? - Are there differences in how Spring Security stores authentication data between WebFlux and Servlet stacks?