Question

So I´m writing an interceptor so when a user tryies to access a page without being logged he gets send back to the login The thing is that my filter is that the condition that checks if a user is logged is always true and whats worst; it also intercept resources (css, images, js) So how should I change my filter so it works?? Here is my code:

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 
        throws IOException, ServletException {
     try {
        // check whether session variable is set
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse res = (HttpServletResponse) response;
        boolean estaLoggeado = false;
        if (req.getSession().getAttribute("estaLoggeado") != null) {
            estaLoggeado = new Boolean("" + req.getSession().getAttribute("estaLoggeado"));
        }
        //  allow user to proccede if url is login.xhtml or user logged in or user is accessing any page in //public folder
        String reqURI = req.getRequestURI();
        System.out.println(reqURI);
        System.out.println("index: " + reqURI.indexOf("/index.xhtml"));
        System.out.println("pages: " + reqURI.indexOf("/pages/"));
        System.out.println("resources: " + reqURI.contains("javax.faces.resource"));
        System.out.println("log: " + estaLoggeado);
        if ((reqURI.indexOf("/index.xhtml") >= 0 || reqURI.indexOf("/pages/") >= 0 || reqURI.contains("javax.faces.resource"))) {
            System.out.println("Si");
            chain.doFilter(request, response);
        } else {   // user didn't log in but asking for a page that is not allowed so take user to login page
            System.out.println("No");
            res.sendRedirect(req.getContextPath() + "/pages/index.xhtml");  // Anonymous user. Redirect to login page
        }
     } catch(Throwable t) {
        System.out.println(t.getMessage());
    }
} //doFilter

Thanks in advance!!

Was it helpful?

Solution

You forgot to check estaLoggeado in the if() block. In other words, you're never actually checking if the user is logged in. You're merely printing to stdout whether the user is logged in.

All in all, this filter's logic is rather clumsy. Those contains() checks on the URI are very poor (note that indexOf(part) >= 0 is effectively exactly the same as contains(part)). What if the part is in the beginning, middle or the ending of an URL? You should be performing exact/starts/ends matching.

Here's a rewrite:

@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 loginURL = request.getContextPath() + "/pages/index.xhtml";

    boolean loggedIn = (session != null) && (session.getAttribute("estaLoggeado") != null);
    boolean loginRequest = request.getRequestURI().equals(loginURL);
    boolean resourceRequest = request.getRequestURI().startsWith(request.getContextPath() + ResourceHandler.RESOURCE_IDENTIFIER + "/");

    if (loggedIn || loginRequest || resourceRequest)) {
        chain.doFilter(request, response); // So, just continue request.
    }
    else {
        response.sendRedirect(loginURL); // So, redirect to login page.
    }
}

(as a side note: I recommend to replace estaLoggeado by user (or usuario if you really need to make your code unreadable to non-English people) so that it represents the whole user instead of just an useless "flag")

Note that this doesn't cover ajax requests. The redirect would fail with no visual feedback when the session is expired during submitting a JSF ajax form. For a more extended filter, head to this answer: Authorization redirect on session expiration does not work on submitting a JSF form, page stays the same.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top