Search code examples
javaspringsessioneventstimeout

Spring boot session timeout event listener


I want to perform a custom event when a user is logged out from a session timeout. The user is successfully logged out after exactly the length of time specified by my application.properties:

server.servlet.session.timeout=10
server.servlet.session.cookie.max-age=10

I have found a few similar solutions which involve a SessionDestroyedEvent, for example:

@Slf4j
@Component
public class SessionExpiredListener implements ApplicationListener<SessionDestroyedEvent> {

    @Override
    public void onApplicationEvent(SessionDestroyedEvent event) {
        for (SecurityContext securityContext : event.getSecurityContexts()) {
            Authentication authentication = securityContext.getAuthentication();
            UserPrincipal user = (UserPrincipal) authentication.getPrincipal(); // UserPrincipal is my custom Principal class
            log.debug("Session expired!" + user.getUsername());
            // do custom event handling
        }
    }
}

The problem is the SessionDestroyedEvent is not triggered at the same time as the session timeout, in my tests it has triggered up to 5 minutes after the session has expired.

I have also tried using sessionDestroyed in HttpSessionListener but with similar results.

Is there an event that will trigger exactly when the session expires, or is there some way to achieve this?


Solution

  • The sessionDestroyed() method is called when the web container expires the session. In Tomcat, session expirations happens every minute, and I think it is the case with other servlet containers. So, even after the session times out there could be a delay until the next detection of expirations.

    Session management is done by servlet container, and your application is getting notification from it. And there is no way to be notified at the exact time of session expiration.