Search code examples
javaicefacesservlet-filtersicefaces-1.8

How to create a Filter for an IceFaces based web application?


I am using IceFaces 1.8.2. I want to create a Filter so that people cannot access unauthorized URLs of my application.

I attempted to created a Filter like this:

public class AuthenticationFilter implements Filter {

    private FilterConfig config;

    public void init(FilterConfig filterConfig) throws ServletException {
        this.config=filterConfig;
    }

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest req=(HttpServletRequest)request;
        HttpServletResponse resp=(HttpServletResponse)response;
        //HttpSession session=req.getSession(true);
        String pageRequested=req.getRequestURL().toString();
        System.out.println("Page Requested="+pageRequested);

        HttpSession session = req.getSession(false);
        if (!session.isNew()) {
          if(ManageCustomerMbeans.AUTH_KEY!=null){
            System.out.println(":::::::::::::::::::::::::Login Authenticate");
            chain.doFilter(req, resp);
          }
        }
        else {
            System.out.println("::::::::::::::::::::::::::Not Authenticate");
          //Session has expired - redirect to login.jsp
        }
    }

    public void destroy() {

    }

}

But the result is that the restricted page still shows if I type in its URL. If I block the other page like this:

if (!(pageRequested.contains("Login.jsp")&&session.getAttribute(ManageCustomerMbeans.AUTH_KEY)==null)) {
    System.out.println("Filter Error!!!");
    resp.sendRedirect("./error");
} else {
    chain.doFilter(request, response);
}

nothing happend too.

How do I properly create a Filter for an IceFaces based web application?

************UPDATE**************

After correction from Mr. BalusC, i do many correction in my Filter class plus a little tweak because iam using icefaces 1.8.2..this is my correction and it works:

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

        HttpServletRequest req=(HttpServletRequest)request;
        HttpServletResponse resp=(HttpServletResponse)response;
        HttpSession session = req.getSession(false);
        String pageRequested=req.getRequestURL().toString();

        String resources="resources/";
        String xmlhttp="xmlhttp/";
        String kaptcha="kaptcha.jpg";
        String block="block/";
        if(pageRequested.contains("login")||pageRequested.contains(resources)
                ||pageRequested.contains(block)||pageRequested.contains(xmlhttp)
                ||pageRequested.contains(kaptcha)||pageRequested.contains("error")
                ||pageRequested.contains("logout")||pageRequested.contains("lsuccess")){

            chain.doFilter(req, resp);
        }else{

            if (session != null && session.getAttribute(ManageUsersMBeans.AUTH_KEY) != null) {

            chain.doFilter(req, resp);
            } else {

                resp.sendRedirect(req.getContextPath() + "/error");
            }
        }



    }

and in web.xml:

    <filter>
        <filter-name>AuthenticationFilter</filter-name>
        <filter-class>com.do.tools.util.AuthenticationFilter</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>AuthenticationFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

Thanks


Solution

  • If the filter is not invoked at all, i.e. the doFilter() method is never executed, then the filter mapping is plain wrong. You need to verify the <filter-mapping> in web.xml. It has to be mapped on either the <servlet-name> of the FacesServlet or on an <url-pattern> covering the restricted pages, such as /app/*, /secured/*, etc, depending on your folder structure.

    If the filter is indeed invoked, then your code logic flow is plain wrong. Let's look at your first attempt:

    HttpSession session = req.getSession(false);
    
    if (!session.isNew()) {
      if(ManageCustomerMbeans.AUTH_KEY!=null){
        chain.doFilter(req, resp);
      }
    } else {
      //Session has expired - redirect to login.jsp
    }
    

    This flow is clearly wrong. First, you're getting the session with false which means that it can potentially return null but you are never checking on that. Then, you're checking if the session has recently been created which can never be true if getSession(false) returns a non-null session. So, the first if block is always entered. Then you're checking if a constant value is not null, but this can never be false as it's apparently a constant. So, your chain.doFilter() is always invoked. Assuming that the constant represents the attribute key, you need to rewrite it as follows:

    HttpSession session = req.getSession(false);
    
    if (session != null && session.getAttribute(ManageCustomerMbeans.AUTH_KEY) != null) {
        chain.doFilter(req, resp);
    } else {
        resp.sendRedirect(req.getContextPath() + "/login.jsp");
    }
    

    This will check if the session is not null and contains the logged-in user. If true, then continue the request, else redirect to the login page. You only need to make sure that the login page is not matched by the filter's mapping, else you need to add an extra check in the if block on the request URI.

    Your second attempt is also wrong:

    if (!(pageRequested.contains("Login.jsp")&&session.getAttribute(ManageCustomerMbeans.AUTH_KEY)==null)) {
        resp.sendRedirect("./error");
    } else {
        chain.doFilter(request, response);
    }
    

    This will always redirect to the error page if the user is not entering the login page. This will only continue the request if the user is entering the login page while not logged-in. This logic makes no sense. But if you says that "it doesn't work", then it can only mean that the filter mapping is wrong.