We have a Vaadin 7 application with a heartbeatInterval of 10 seconds, a session-timeout of 1 minute, and closeIdleSessions set to true. The vaadin session times out after the 1 minute, and a dialog pops up on the page saying the session has expired (after the next heartbeat). However, the HttpSession does not expire for another 2 minutes after that. When clicking the pop-up, or refreshing the page, it is reusing the same HttpSession. We have a few session scoped beans that handle user auth data that are sticking around during that time, which ends up causing the new request to auto log in the user.
With a session destroy listener, I can manually clear out that session scope user auth bean to prevent the auto-login, but why is the HttpSession living beyond Vaadin session? I tried manually invalidating the WrappedSession from the VaadinService, but I can’t seem to get to the HttpSession. Maybe because the Vaadin session is already destroyed.
web.xml
heartbeatInterval
10
closeIdleSessions
true
1
When setting the heartbeat to 300 seconds and session timeout to 40 minutes, the HttpSession stays alive a lot longer.
I’ve had trouble with that as well, and I’m curious about solutions for it.
What I’ve done isn’t pretty, but perhaps it can help you paper over the problem…
I’ve configured vaadin to redirect to a special url instead of showing the session expired notification (in our custom VaadinServlet):
@Override
protected void servletInitialized() throws ServletException {
super.servletInitialized();
getService().setSystemMessagesProvider((SystemMessagesProvider) systemMessagesInfo -> {
CustomizedSystemMessages messages = new CustomizedSystemMessages();
// Don't show any messages, redirect immediately to the session expired URL
messages.setSessionExpiredNotificationEnabled(false);
// Force a logout to also end the HTTP session and not only the Vaadin session
messages.setSessionExpiredURL("sessionExpired");
// Don't show any message, reload the page instead
messages.setCommunicationErrorNotificationEnabled(false);
return messages;
});
}
We’re using spring, so I created the session expired endpoint, and I’m invalidating the session manually there:
[code] @Controller
public class SessionExpiredController {
@RequestMapping("/sessionExpired")
public View sessionExpired(HttpServletRequest request) {
request.getSession().invalidate();
return new RedirectView("login?sessionExpired", true);
}
}
[/code]This redirects to our login-endpoint, we use the url parameter to display a label that says the session timed out.
Using the session destroy listener to clear the authentication didn’t work for us, because we use a session registry, and that could lead to problems (if the registry was notified after our listener was run, it wouldn’t notice that a session for a principal has expired).
Anyway, I hope someone with more expierience than me can shed some light on the underlying problem.