views:

166

answers:

4

Case 1: Log out : Once we log out, if one tries to access previous, it must automatically redirect to login.jsp

Case 2: Session expired : If session expires when user is still logged in, it must try to automatically redirect to sessionExpired.jsp when previous page is accessed.

How to differentiate ? I am currently invalidating session when logging out.

+1  A: 

If it were me I would clear the session on log out and create a bool in it called HasLoggedOut then set this to true. Then if this bool exists in session you know they logged out, if it doesn't then the session has either timed out or the user never logged in at all.

As you still cant differentiate between timed out and not logged in I normally make the decision that if they request an authenticated page I will just send them to session timeout page which also doubles as a login page that says something like

"Oops, we don't know who you are, either your session has timed out or you have not yet logged in please login below"

This then caters for both scenarios

Gavin Draper
Thanks. Its a good idea, however displaying you are new user or your session is timed out doesn't look good.
Prabhat
+5  A: 

On login, set a cookie with a long expiry (> 24 hours). Remove this cookie at logout time by setting the maxage to 0.

You can have check for any non-logged in user (i.e. invalid session id). If the cookie does not exist, redirect him to login.jsp

If the cookie exists, it means his session expired so redirect him to session-expired.jsp

JoseK
Thanks. I am going to implement this.
Prabhat
@jose: if i try to recreate a cookie using firefox webdeveloper plugin , the code may fail.
Suresh S
A: 

Your idea can be implemented Gavin without changing the message. Here is how

            if (request.getSession().getAttribute("HasLoggedOut") != null && request.getSession().getAttribute("usernameStoredInPreviousSession") == null) {
                response.sendRedirect("sessionExpired.html");
            }else if(request.getSession().getAttribute("usernameStoredInPreviousSession") == null){ 
                response.sendRedirect("index.html");    
            }else { //Do your stuff }
Prabhat
Nope.. Sorry.. This wont work
Prabhat
+1  A: 

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.
BalusC