Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Servlet filter: I have to add headers before passing to the chain, documentation tells otherwise

We're currently working on adding headers to each response from our application. To add these headers we're using the Servlet APIs Filter-interface.

We've got the following filter in our application:

public class SecurityFilter implements Filter
{
    @Override
    public void init(FilterConfig filterConfig) throws ServletException
    {

    }

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

        HttpServletResponse httpServletResponse = ((HttpServletResponse) response);
        httpServletResponse.addHeader("X-Frame-Options", "DENY");
        httpServletResponse.addHeader("X-Content-Type-Options", "nosniff");
    }

    @Override
    public void destroy()
    {

    }
}

This (specifically the doFilter-method) is implemented correctly according to the documentation, which suggests the following order of work:

  1. Examine the request
  2. Optionally wrap the request object with a custom implementation to filter content or headers for input filtering
  3. Optionally wrap the response object with a custom implementation to filter content or headers for output filtering

    • Either invoke the next entity in the chain using the FilterChain object (chain.doFilter()),
    • or not pass on the request/response pair to the next entity in the filter chain to block the request processing
  4. Directly set headers on the response after invocation of the next entity in the filter chain.

As far as we can see, the order of our doFilter-method is correct according to the documentation (pass the request to the chain first as stated under point 4, add custom headers afterwards as stated under point 5). However, the headers we add aren't visible in the responses. If we change to order to the following, everything seems to work just fine:

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException
{
    HttpServletResponse httpServletResponse = ((HttpServletResponse) response);
    httpServletResponse.addHeader("X-Frame-Options", "DENY");
    httpServletResponse.addHeader("X-Content-Type-Options", "nosniff");

    chain.doFilter(request, response);
}

Can anyone explain this behavior?

like image 992
Bas Dalenoord Avatar asked May 20 '15 07:05

Bas Dalenoord


People also ask

How does servlet filter chain work?

A Servlet Filters is an object that is used to perform filtering tasks such as conversion, encryption, decryption, etc. The servlet filter entry is done in a file named web. xml. If the entry is removed from this file, then we do not need to change the servlet, and the filter will be automatically removed.

What is servlet and servlet filter Why do we need servlet filters?

Servlet Filters are pluggable java components that we can use to intercept and process requests before they are sent to servlets and response after servlet code is finished and before container sends the response back to the client.

Which tasks are performed by the servlet filter select all that apply?

It is mainly used to perform filtering tasks such as conversion, logging, compression, encryption and decryption, input validation etc.

What is the main functionality of a servlet filter?

A filter is an object that is invoked at the preprocessing and postprocessing of a request on the server, i.e., before and after the execution of a servlet for filtering the request. Filter API (or interface) includes some methods which help us in filtering requests.


1 Answers

Oracle tells you to wrap the response before passing it down the chain, if you want to add something after chain.doFilter(..)

Note that if you want to preprocess the request object or postprocess the response object, you cannot directly manipulate the original request or response object. You must use wrappers. When postprocessing a response, for example, the target servlet has already completed and the response could already be committed by the time a filter would have a chance to do anything with the response. You must pass a response wrapper instead of the original response in the chain doFilter() call. See "Using a Filter to Wrap and Alter the Request or Response".

http://docs.oracle.com/cd/B32110_01/web.1013/b28959/filters.htm#BCFCIHAH

like image 72
lrxw Avatar answered Sep 28 '22 14:09

lrxw