5

I've written a filter class to add a P3P header to every page. I added this to my web.xml:

<filter>
    <filter-name>AddP3pHeaderFilter</filter-name>
    <filter-class>com.mycompany.AddP3pHeaderFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>AddP3pHeaderFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

It adds the header to every page request, but it doesn't work when the user first logs in. The user submits the form to j_security_check, but the response doesn't include the header. How can I make my filter apply to the login request?

2
  • +1: for adding searchable knowledge to the community
    – mkoeller
    Commented Mar 26, 2009 at 19:10
  • Drat. Actually my solution didn't work, so I guess this is a normal question after all. Commented Mar 26, 2009 at 19:35

5 Answers 5

4

The login request forwards to the appropriate page. By default, filters only apply to REQUEST dispatches. You need to modify the web.xml as follows:

<filter>
    <filter-name>AddP3pHeaderFilter</filter-name>
    <filter-class>com.mycompany.AddP3pHeaderFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>AddP3pHeaderFilter</filter-name>
    <url-pattern>/*</url-pattern>
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>FORWARD</dispatcher>
</filter-mapping>

EDIT: I thought this had fixed it, but I was mistaken.

0
1

Doesn't work in Tomcat.

I ended up having to use Tomcat valves.

0

Most servletcontainers indeed does not allow hooks on /j_security_check requests due to security reasons. Some older versions will do, but that should be fixed in newer versions.

The best way to hook on this anyway would be to check the presence of the user principal in the HttpSession which you've manually put there if absent.

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
    HttpServletRequest httpRequest = (HttpServletRequest) request;
    UserPrincipal user = httpRequest.getUserPrincipal();
    HttpSession session = httpRequest.getSession();
    if (user != null && session.getAttribute("user") == null) {
        session.setAttribute("user", user);

        // First-time login. You can do your intercepting thing here.
    }
    chain.doFilter(request, response);
}
1
  • If I recall correctly, the doFilter method wasn't even being called when the user logged in. I'll update my accepted answer with what I ended up doing. Commented Apr 15, 2010 at 16:43
0

Don't know about tomcat, but it works for me in jetty, just put your filter before spring filter :

<filter>
    <filter-name>AddP3pHeaderFilter</filter-name>
    <filter-class>com.mycompany.AddP3pHeaderFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>AddP3pHeaderFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

<filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>

<filter-mapping>
  <filter-name>springSecurityFilterChain</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>
0

My web.xml

<filter>
        <description>
        FBIS Filter</description>
        <display-name>Fbisfilter</display-name>
        <filter-name>Fbisfilter</filter-name>
        <filter-class>fbis.filter.Fbisfilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>Fbisfilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

and myfilter is

package fbis.filter;

import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

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;
import javax.servlet.http.HttpSession;

import com.sqlconnection.SQLConnect;
import com.sun.security.auth.UserPrincipal;

import fbis.interfaces.abstractclasses.Connections;

/**
 * Servlet Filter implementation class Fbisfilter
 */
public class Fbisfilter extends Object implements Filter,Connections {
    public void destroy() {
    //  System.out.println("Filter Service finished");
    }
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        HttpServletResponse httpresponse = (HttpServletResponse) response;
        System.out.println("FILTER INSIDE");
    // place your code here
        HttpSession session = httpRequest.getSession(true);
        String usrid = httpRequest.getParameter("txtuname");
        String pwd = httpRequest.getParameter("txtpassword");
        PreparedStatement pstmt;
        try {
            pstmt = con
                    .prepareStatement("SELECT l.Userid,n.First_name from Login_details_dtls l join New_Registration_dtls n on l.Userid=n.Userid where n.Userid=? AND l.pwd=?");
        pstmt.setString(1, usrid);
        pstmt.setString(2, pwd);
        ResultSet rs = pstmt.executeQuery();
        if (rs.next()) {
            session.setAttribute("usr", rs.getString("Userid"));
            session.setAttribute("usrname", rs.getString("First_name"));
        }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        chain.doFilter(httpRequest, httpresponse);
    }

    /**
     * @see Filter#init(FilterConfig)
     */
    public void init(FilterConfig fConfig) throws ServletException {
        System.out.println("Filter Service has started");
    }

}

Not the answer you're looking for? Browse other questions tagged or ask your own question.