views:

719

answers:

3

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?

+1  A: 

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.

Jeremy Stein
+1  A: 

Doesn't work in Tomcat.

I ended up having to use Tomcat valves.

Jeremy Stein
A: 

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);
}
BalusC
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.
Jeremy Stein