46

I'm running a web application in JBoss AS 5. I also have a servlet filter which intercepts all the requests to the server. Now, I want to redirect the users to the login page, if the session has expired. I need to do this 'isSessionExpired()' check in the filter and need to redirect the user accordingly. How do I do it? I'm setting my session time limit in web.xml, as below:

<session-config>
    <session-timeout>15</session-timeout>
</session-config>
Joshua Taylor
  • 84,998
  • 9
  • 154
  • 353
Veera
  • 32,532
  • 36
  • 98
  • 137

9 Answers9

58

You could use a Filter and do the following test:

HttpSession session = request.getSession(false);// don't create if it doesn't exist
if(session != null && !session.isNew()) {
    chain.doFilter(request, response);
} else {
    response.sendRedirect("/login.jsp");
}

The above code is untested.

This isn't the most extensive solution however. You should also test that some domain-specific object or flag is available in the session before assuming that because a session isn't new the user must've logged in. Be paranoid!

Community
  • 1
  • 1
Alex
  • 8,093
  • 6
  • 49
  • 79
  • Yes, that's true. That would be a 3rd argument (value being passed in) for the optional 3rd parameter (for the method definition) in the method, but doFilter is a method of the object "chain" in your code. Where is "chain" set above that line of code in your source code? – JustBeingHelpful Oct 11 '15 at 08:16
  • 1
    I don't know what you're referring to with regards to optional 3rd parameters. The `chain` variable is passed in to your implementation of `doFilter`, by the container. It is implied in this answer that the code is inside the `doFilter`. – Alex Oct 11 '15 at 08:44
  • @MacGyver chain is the object of FilterChain Class that is present in doFilter method. – Rohit Oct 19 '16 at 10:53
21

How to redirect to Login page when Session is expired in Java web application?

This is a wrong question. You should differentiate between the cases "User is not logged in" and "Session is expired". You basically want to redirect to login page when user is not logged in. Not when session is expired. The currently accepted answer only checks HttpSession#isNew(). But this obviously fails when the user has sent more than one request in the same session when the session is implicitly created by the JSP or what not. E.g. when just pressing F5 on the login page.

As said, you should instead be checking if the user is logged in or not. Given the fact that you're asking this kind of question while standard authentication frameworks like j_security_check, Shiro, Spring Security, etc already transparently manage this (and thus there would be no need to ask this kind of question on them), that can only mean that you're using a homegrown authentication approach.

Assuming that you're storing the logged-in user in the session in some login servlet like below:

@WebServlet("/login")
public class LoginServlet extends HttpServlet {

    @EJB
    private UserService userService;

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.getRequestDispatcher("/WEB-INF/login.jsp").forward(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        User user = userService.find(username, password);

        if (user != null) {
            request.getSession().setAttribute("user", user);
            response.sendRedirect(request.getContextPath() + "/home");
        } else {
            request.setAttribute("error", "Unknown login, try again");
            doGet(request, response);
        }
    }

}

Then you can check for that in a login filter like below:

@WebFilter("/*")
public class LoginFilter implements Filter {

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws ServletException, IOException {    
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;
        HttpSession session = request.getSession(false);
        String loginURI = request.getContextPath() + "/login";

        boolean loggedIn = session != null && session.getAttribute("user") != null;
        boolean loginRequest = request.getRequestURI().equals(loginURI);

        if (loggedIn || loginRequest) {
            chain.doFilter(request, response);
        } else {
            response.sendRedirect(loginURI);
        }
    }

    // ...
}

No need to fiddle around with brittle HttpSession#isNew() checks.

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
8

you can also do it with a filter like this:

public class RedirectFilter implements Filter {

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    HttpServletRequest req=(HttpServletRequest)request;

    //check if "role" attribute is null
    if(req.getSession().getAttribute("role")==null) {
        //forward request to login.jsp
        req.getRequestDispatcher("/login.jsp").forward(request, response);
    } else {
        chain.doFilter(request, response);
    }
}
}
Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
kafrlust
  • 299
  • 3
  • 11
  • This can also throw a NULL pointer exception when you try to read the attribute if getSession returns null. – Swaprks Apr 17 '15 at 06:40
  • 2
    Also you may have some pages where user is not logged in. i.e registration pages where you wont get any role. – The Java Guy Aug 04 '15 at 02:46
5

Check for session is new.

HttpSession session = request.getSession(false);
if (!session.isNew()) {
  // Session is valid
}
else {
  //Session has expired - redirect to login.jsp
}
zkarthik
  • 949
  • 1
  • 10
  • 18
  • 9
    Your snippet is susceptible to null pointer exceptions. Passing false to `getSession` will not create a session if one doesn't exist and will therefore return null. – Alex Oct 11 '11 at 14:56
  • @Yeti, then why to check isNew() at all when we can do the same with one null check!! :) – Jaikrat Feb 03 '14 at 13:39
  • @zkarthik Nullpointer exception in case of session timeouts "if only it was this easy" the as null.isNew() will occur when session is equal to null which will trigger exception – codefreaK Dec 26 '14 at 08:36
5

Inside the filter inject this JavaScript which will bring the login page like this. If you don't do this then in your AJAX call you will get login page and the contents of login page will be appended.

Inside your filter or redirect insert this script in response:

String scr = "<script>window.location=\""+request.getContextPath()+"/login.do\"</script>";
response.getWriter().write(scr);
Paul Croarkin
  • 14,496
  • 14
  • 79
  • 118
mukut
  • 130
  • 3
  • 3
4

You need to implement the HttpSessionListener interface, server will notify session time outs.

like this;

import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

public class ApplicationSessionListener implements HttpSessionListener {

public void sessionCreated(HttpSessionEvent event) {
   System.out.println("Session Created");
 }

public void sessionDestroyed(HttpSessionEvent event) {
   //write your logic
   System.out.println("Session Destroyed");
  }
 }

Check this example for better understanding

http://www.myjavarecipes.com/how-to-catch-session-timeouts/

Irshad
  • 3,071
  • 5
  • 30
  • 51
Sunil Pidugu
  • 215
  • 2
  • 5
2

Until the session timeout we get a normal request, after which we get an Ajax request. We can identify it the following way:

String ajaxRequestHeader = request.getHeader("X-Requested-With");
if ("XMLHttpRequest".equals(ajaxRequestHeader)) {
    response.sendRedirect("/login.jsp");
}
Stefan van den Akker
  • 6,661
  • 7
  • 48
  • 63
Anirudh Jadhav
  • 967
  • 1
  • 9
  • 23
0

i found this posible solution:

public void logout() {
    ExternalContext ctx = FacesContext.getCurrentInstance().getExternalContext();
    String ctxPath = ((ServletContext) ctx.getContext()).getContextPath();
    try {
        //Use the context of JSF for invalidate the session,
        //without servlet
        ((HttpSession) ctx.getSession(false)).invalidate();
        //redirect with JSF context.
        ctx.redirect(ctxPath + "absolute/path/index.jsp");
    } catch (IOException ex) {
        System.out.println(ex.getMessage());
    }
}
LoGos
  • 1
-3

When the use logs in, put its username in the session:

`session.setAttribute("USER", username);`

At the beginning of each page you can do this:

<%
String username = (String)session.getAttribute("USER");
if(username==null) 
// if session is expired, forward it to login page
%>
<jsp:forward page="Login.jsp" />
<% { } %>
sampath
  • 155
  • 1
  • 2
  • 7