So here is the problem. When a user logs out of my website, they can still hit the back button and continue using the site. To keep track of whether the user is logged in or not
All my JSP's have no-cache headers (via @include directives). I have a logout.jsp in the root of the app with the following lines:
HttpSession sessIfAny = request.getSession(false);
if (sessIfAny != null) sessIfAny.invalidate();
This prevents creating unnecessary sessions.
The web.xml needs to exempt logout.jsp from authentication:
<!-- Resources excepted from authentication -->
<security-constraint>
<web-resource-collection>
<web-resource-name>excepted</web-resource-name>
<url-pattern>/logout.jsp</url-pattern>
<url-pattern>/favicon.ico</url-pattern>
<!-- ... other resources -->
</web-resource-collection>
<!-- no auth-constraint -->
</security-constraint>
This prevents a login page being shown to do a logout on an expired session.
You shouldn't check if the session is still active on your destination page, it's better to check it with a Filter
.
If in the filter, request.getSession().getAttribute("isActive")
returns something, then the user is still logged, and you simply chain; else you redirect on the login page.
For example :
public class ActiveFilter implements Filter {
public void init(FilterConfig filterConfig)
}
public void destroy() {
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
if (req.getSession().getAttribute("isActive") == null){
res.sendRedirect("/index.jsp");
}else{
chain.doFilter(request, response);
}
}
}
Resources :
The meta tags are not sufficient. You need to add them as fullworthy response headers. The webbrowser relies on them. A Filter
is helpful in this. Also, the Cache-Control
header is incomplete (won't work as expected in Firefox, among others).
Implement this in the doFilter()
method of a Filter
which is mapped on an url-pattern
of for example *.jsp
(if you want to cover all JSP pages).
HttpServletResponse res = (HttpServletResponse) response;
res.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1.
res.setHeader("Pragma", "no-cache"); // HTTP 1.0.
res.setDateHeader("Expires", 0); // Proxies.
chain.doFilter(request, response);
This way the webbrowser will be forced to fire a real request on the server rather than displaying the page from the browser cache. Also, you should rather be using a Filter
to check the presence of the logged-in user, not JSP/JSTL.