happy
happy

Reputation: 2628

Web Filter in JSF

I am implementing web filter through refering this link

My code is

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    id="WebApp_ID" version="2.5">
    <display-name>project_name</display-name>
    <welcome-file-list>
        <welcome-file>/project_name/faces/jsp/HomePage.jsp</welcome-file>
    </welcome-file-list>
    <servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>/faces/*</url-pattern>
    </servlet-mapping>
    <context-param>
        <description>State saving method: 'client' or 'server' (=default). See JSF Specification 2.5.2</description>
        <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
        <param-value>client</param-value>
    </context-param>
    <context-param>
        <param-name>javax.servlet.jsp.jstl.fmt.localizationContext</param-name>
        <param-value>resources.application</param-value>
    </context-param>

    <context-param>
        <param-name>org.richfaces.CONTROL_SKINNING</param-name>
        <param-value>enable</param-value>
    </context-param>
    <context-param>
        <param-name>org.richfaces.LoadScriptStrategy</param-name>
        <param-value>ALL</param-value>
    </context-param>
    <context-param>
        <param-name>org.richfaces.LoadStyleStrategy</param-name>
        <param-value>ALL</param-value>
    </context-param>
    <context-param>
        <param-name>org.ajax4jsf.DEFAULT_EXPIRE</param-name>
        <param-value>2764800</param-value>
    </context-param>
    <context-param>
        <param-name>org.apache.myfaces.ERROR_HANDLING</param-name>
        <param-value>false</param-value>
    </context-param>
    <context-param>
        <param-name>org.ajax4jsf.handleViewExpiredOnClient</param-name>
        <param-value>true</param-value>
    </context-param>

    <filter>
        <display-name>RichFaces Filter</display-name>
        <filter-name>richfaces</filter-name>
        <filter-class>org.ajax4jsf.Filter</filter-class>
        <init-param>
            <param-name>createTempFiles</param-name>
            <param-value>false</param-value>
        </init-param>
        <init-param>
            <param-name>maxRequestSize</param-name>
            <param-value>20000000</param-value>
        </init-param>
        <init-param>
            <param-name>enable-cache</param-name>
            <param-value>true</param-value>
        </init-param>


    </filter>

    <filter>
        <filter-name>loginFilter</filter-name>
        <filter-class>com.common.LoginFilter</filter-class>
    </filter>

     <filter-mapping>
        <filter-name>loginFilter</filter-name>
        <url-pattern>/faces/*</url-pattern>
    </filter-mapping>

    <filter-mapping>
        <filter-name>richfaces</filter-name>
        <servlet-name>Faces Servlet</servlet-name>
        <dispatcher>REQUEST</dispatcher>
        <dispatcher>FORWARD</dispatcher>
        <dispatcher>INCLUDE</dispatcher>
    </filter-mapping>

    <listener>
        <listener-class>com.sun.faces.config.ConfigureListener</listener-class>
    </listener>
    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>*.jsf</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>*.faces</url-pattern>
    </servlet-mapping>
    <servlet>
        <servlet-name>Resource Servlet</servlet-name>
        <servlet-class>org.primefaces.resource.ResourceServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>Resource Servlet</servlet-name>
        <url-pattern>/primefaces_resource/*</url-pattern>
    </servlet-mapping>
</web-app>

LoginFilter.class

public class LoginFilter implements Filter {

    @Override
    public void init(FilterConfig config) throws ServletException {
        // If you have any <init-param> in web.xml, then you could get them
        // here by config.getInitParameter("name") and assign it as field.
    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        System.out.println("Inside Login Filter");
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;
        HttpSession session = request.getSession(false);
System.out.println("session..."+ session);
        if (session == null || session.getAttribute(IConstants.HAS_USER_ID) == null) {
            response.sendRedirect(request.getContextPath() + "/faces/jsp/login.jsp"); // No logged-in user found, so redirect to login page.
        } else {
            chain.doFilter(req, res); // Logged-in user found, so just continue request.
        }
    }

    @Override
    public void destroy() {
        // If you have assigned any expensive resources as field of
        // this Filter class, then you could clean/close them here.
    }

}

Setting the session variable after successful login

FacesContext.getCurrentInstance().getExternalContext()
                .getSessionMap()
                .put(IConstants.HAS_USER_ID, IConstants.HAS_USER_ID);

But the problem I am facing is I keep getting below log

Inside Login Filter
session...org.apache.catalina.session.StandardSessionFacade@1c134e1

in console and page is never redirected to next page or login page.

Upvotes: 5

Views: 16846

Answers (2)

Sacky San
Sacky San

Reputation: 1662

I implemented a Cache filter. here is the code. See if this helps

Add following in your web.xml

<filter>
    <filter-name>cache</filter-name>
    <filter-class>au.com.webapp.config.CacheFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>cache</filter-name>
    <url-pattern>*.xhtml</url-pattern>
</filter-mapping>

In your au.com.webapp.config package create a class CacheFilter as follows:

package au.com.webapp.config;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class CacheFilter implements Filter {
    private static long maxAge = 86400 * 30; // 30 days in seconds

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        HttpServletResponse httpResponse = (HttpServletResponse) response;
        String uri = ((HttpServletRequest) request).getRequestURI();
        if (uri.contains(".js") || uri.contains(".css") || uri.contains(".svg") || uri.contains(".gif")
                || uri.contains(".woff") || uri.contains(".png")) {
            httpResponse.setHeader("Cache-Control", "max-age=" + maxAge);
        }
        chain.doFilter(request, response);
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("Cache Filter started: ");

    }

    @Override
    public void destroy() {
    }
}

Upvotes: 0

BalusC
BalusC

Reputation: 1108642

It's because your filter also matches the request on the login page. It's basically running in an infinite loop redirecting to the login page. There are basically 2 options:

  1. Make sure that the login URL is not covered by the filter mapping. Put the restricted pages in a folder like /secured/*, /app/*, etc and map the filter on exactly that URL pattern and put the login page there outside.

  2. Check in the filter if the login URL is not currently been requested.

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;
        HttpSession session = request.getSession(false);
        boolean loggedIn = (session != null) ? session.getAttribute(IConstants.HAS_USER_ID) != null : false;
        String loginURL = request.getContextPath() + "/faces/jsp/login.jsp"; 
    
        if (!loggedIn && !request.getRequestURI().equals(loginURL)) {       
            response.sendRedirect(loginURL);
        } else {
            chain.doFilter(request, response);
        }
    }
    

Upvotes: 8

Related Questions