How to fix "Session was invalidated" Exception?
Asked Answered
S

1

8

I have an endpoint (/logout) that invalidate the session manually by calling HttpSession#invalidate(). Sometimes i got the following exception (Within 1000 request it happens about a dozen times):

java.lang.IllegalStateException: Session was invalidated
at org.springframework.session.data.redis.RedisSessionRepository.save(RedisSessionRepository.java:129)
at org.springframework.session.data.redis.RedisSessionRepository.save(RedisSessionRepository.java:45)
at org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper.commitSession(SessionRepositoryFilter.java:229)
at org.springframework.session.web.http.SessionRepositoryFilter.doFilterInternal(SessionRepositoryFilter.java:145)
at org.springframework.session.web.http.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:82)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:352)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:268)
        2 lines skipped for [org.apache.catalina]
at org.springframework.web.filter.ServerHttpObservationFilter.doFilterInternal(ServerHttpObservationFilter.java:109)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
        2 lines skipped for [org.apache.catalina]

It looks like that the session is tried to be saved after it was invalidated. Is there way to prevent a save after the session was invalidated or is there a way to make sure the invalidate state is written after the save?

I found a similar case here https://github.com/spring-projects/spring-security/pull/9128#issuecomment-984972101 but there it is related to spring security.

I looks to me that there is a current session object at SessionRepositoryFilter#commitSession() although it should have been removed from the current request.

Spring boot 3.2.3 (without spring security), Spring Cloud dependecy 2023.0.1, Redisson and RedisIndexedSessionRepository with flushmode:on_save and savemode:on_set_attribute is used. The service is behind spring cloud gateway.

It's seems that Spring cloud gateway has an impact on this error. When i do a test without the gateway the exception does not happen.

Sheeb answered 11/3 at 11:48 Comment(0)
S
0

What helped to reduce the number of exceptions is to set flushMode to IMMEDIATE.

@EnableRedisHttpSession(redisNamespace = "my_session",flushMode = FlushMode.IMMEDIATE,saveMode = SaveMode.ON_SET_ATTRIBUTE)

An other improvement is to catch the exception and ignore it. But it might have some side effects...

public class SessionRequestFilter extends OncePerRequestFilter {


  @Override
  protected void doFilterInternal(@NonNull final HttpServletRequest request,
                                  @NonNull final HttpServletResponse response,
                                  @NonNull final FilterChain filterChain) throws ServletException,
                                                                                 IOException {
    try {
      filterChain.doFilter(request, response);
    } catch (IllegalStateException e) {
      if (!"Session was invalidated".equals(e.getMessage())) {
        throw e;
      }
    }
  }
}


  @Bean
  public FilterRegistrationBean<SessionOncePerRequestValidator> sessionFilter(){
    SessionRequestFilter filter =  new SessionRequestFilter ();
    FilterRegistrationBean<SessionOncePerRequestValidator> registration = new FilterRegistrationBean<>(filter);
    registration.setOrder(SessionRepositoryFilter.DEFAULT_ORDER - 1);
    return registration;
  }
Sheeb answered 19/9 at 5:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.