You can test expired sessions by checking if HttpServletRequest#getRequestedSessionId()
doesn't return null
(which means that the client has sent a session cookie and thus assumes that the session is still valid) and HttpServletRequest#isRequestedSessionIdValid()
returns false
(which means that the session has been expired at the server side).
In a nut:
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
HttpServletRequest hsr = (HttpServletRequest) request;
if (hsr.getRequestedSessionId() != null && !hsr.isRequestedSessionIdValid()) {
response.sendRedirect("sessionexpired");
} else if (hsr.getSession().getAttribute("user") == null) {
response.sendRedirect("login");
} else {
chain.doFilter(request, response);
}
}
No need to hassle with extra cookies. Map this Filter
on an url-pattern
covering the protected pages (and thus excluding the sessionexpired and login pages!).
Also, do not invalidate the session on logout, but rather just remove the logged-in user.
session.removeAttribute("user");
Finally don't forget to disable page caching by the browser on the protected pages, otherwise the webbrowser will load them from the cache when you're going back in the browser history, instead of sending a new request to the server. You can achieve this by doing the following in the same filter, before Chain#doFilter()
call.
response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1.
response.setHeader("Pragma", "no-cache"); // HTTP 1.0.
response.setDateHeader("Expires", 0); // Proxies.