Class ForwardedHeaderFilter

All Implemented Interfaces:
jakarta.servlet.Filter, org.springframework.beans.factory.Aware, org.springframework.beans.factory.BeanNameAware, org.springframework.beans.factory.DisposableBean, org.springframework.beans.factory.InitializingBean, org.springframework.context.EnvironmentAware, org.springframework.core.env.EnvironmentCapable, ServletContextAware

public class ForwardedHeaderFilter extends OncePerRequestFilter
Extract values from the standard "Forwarded" header or the "X-Forwarded-*" alternative header, wrap the request and response, and make them reflect the originating client's perspective.

An application cannot know if forwarded headers were added by a trusted proxy or by a malicious client. It is imperative that a proxy at the edge of trust is configured to drop forwarded headers from the outside, including both the standard "Forwarded" header and the "X-Forwarded-*" alternative headers.

Proxies are typically configured to support either the standard "Forwarded" header or the "X-Forwarded-*" header. Accordingly, an application must indicate which of the two alternatives it expects through a constructor argument.

Support for "X-Forwarded-Prefix" is enabled separately via setUseForwardedPrefix(boolean).

You can configure this filter in removeOnly mode, in which case it hides the headers without using them.

Since:
4.3
Author:
Rossen Stoyanchev, EddĂș MelĂ©ndez, Rob Winch, Brian Clozel, Mengqi Xu
See Also:
  • Constructor Details

    • ForwardedHeaderFilter

      public ForwardedHeaderFilter()
      A default constructor with the historic behavior so far, which is to check both the standard "Forwarded" header and the "X-Forwarded-*" alternative headers in that order, also with "X-Forwarded-Prefix" enabled by default.

      This behavior depends on proxies being configured correctly to clear both standard "Forwarded" and "X-Forwarded-*" header values coming from the outside. We recommend to use ForwardedHeaderFilter(boolean) intead.

    • ForwardedHeaderFilter

      public ForwardedHeaderFilter(boolean useStandardHeader)
      Create an instance of the filter and specify whether it should use the standard "Forwarded" header or the "X-Forwarded-*" alternative headers.

      "X-Forwarded-Prefix" is enabled separately via setUseForwardedPrefix(boolean).

      Parameters:
      useStandardHeader - whether to use the standard "Forwarded" header (true), or the "X-Forwarded-*" alternative headers (false).
      Since:
      6.1.29
  • Method Details

    • setUseForwardedPrefix

      public void setUseForwardedPrefix(boolean useForwardedPrefix)
      Enable use of "X-Forwarded-Prefix" to determine the context path.

      By default, this is set to "false" in which case the header is ignored.

      Since:
      6.1.29
    • setRemoveOnly

      public void setRemoveOnly(boolean removeOnly)
      Enables mode in which any "Forwarded" or "X-Forwarded-*" headers are removed only and the information in them ignored.
      Parameters:
      removeOnly - whether to discard and ignore forwarded headers
      Since:
      4.3.9
    • setRelativeRedirects

      public void setRelativeRedirects(boolean relativeRedirects)
      Use this property to enable relative redirects as explained in RelativeRedirectFilter, and also using the same response wrapper as that filter does, or if both are configured, only one will wrap.

      By default, if this property is set to false, in which case calls to HttpServletResponse.sendRedirect(String) are overridden in order to turn relative into absolute URLs, also taking into account forwarded headers.

      Parameters:
      relativeRedirects - whether to use relative redirects
      Since:
      4.3.10
    • shouldNotFilter

      protected boolean shouldNotFilter(jakarta.servlet.http.HttpServletRequest request)
      Description copied from class: OncePerRequestFilter
      Can be overridden in subclasses for custom filtering control, returning true to avoid filtering of the given request.

      The default implementation always returns false.

      Overrides:
      shouldNotFilter in class OncePerRequestFilter
      Parameters:
      request - current HTTP request
      Returns:
      whether the given request should not be filtered
    • shouldNotFilterAsyncDispatch

      protected boolean shouldNotFilterAsyncDispatch()
      Description copied from class: OncePerRequestFilter
      The dispatcher type jakarta.servlet.DispatcherType.ASYNC means a filter can be invoked in more than one thread over the course of a single request. Some filters only need to filter the initial thread (for example, request wrapping) while others may need to be invoked at least once in each additional thread for example for setting up thread locals or to perform final processing at the very end.

      Note that although a filter can be mapped to handle specific dispatcher types via web.xml or in Java through the ServletContext, servlet containers may enforce different defaults with respect to dispatcher types. This flag enforces the design intent of the filter.

      The default return value is "true", which means the filter will not be invoked during subsequent async dispatches. If "false", the filter will be invoked during async dispatches with the same guarantees of being invoked only once during a request within a single thread.

      Overrides:
      shouldNotFilterAsyncDispatch in class OncePerRequestFilter
    • shouldNotFilterErrorDispatch

      protected boolean shouldNotFilterErrorDispatch()
      Description copied from class: OncePerRequestFilter
      Whether to filter error dispatches such as when the servlet container processes and error mapped in web.xml. The default return value is "true", which means the filter will not be invoked in case of an error dispatch.
      Overrides:
      shouldNotFilterErrorDispatch in class OncePerRequestFilter
    • doFilterInternal

      protected void doFilterInternal(jakarta.servlet.http.HttpServletRequest request, jakarta.servlet.http.HttpServletResponse response, jakarta.servlet.FilterChain filterChain) throws jakarta.servlet.ServletException, IOException
      Description copied from class: OncePerRequestFilter
      Same contract as for doFilter, but guaranteed to be just invoked once per request within a single request thread. See OncePerRequestFilter.shouldNotFilterAsyncDispatch() for details.

      Provides HttpServletRequest and HttpServletResponse arguments instead of the default ServletRequest and ServletResponse ones.

      Specified by:
      doFilterInternal in class OncePerRequestFilter
      Throws:
      jakarta.servlet.ServletException
      IOException
    • formatRequest

      protected String formatRequest(jakarta.servlet.http.HttpServletRequest request)
      Format the request for logging purposes including HTTP method and URL.
      Parameters:
      request - the request to format
      Returns:
      the String to display, never empty or null
    • doFilterNestedErrorDispatch

      protected void doFilterNestedErrorDispatch(jakarta.servlet.http.HttpServletRequest request, jakarta.servlet.http.HttpServletResponse response, jakarta.servlet.FilterChain filterChain) throws jakarta.servlet.ServletException, IOException
      Description copied from class: OncePerRequestFilter
      Typically an ERROR dispatch happens after the REQUEST dispatch completes, and the filter chain starts anew. On some servers however the ERROR dispatch may be nested within the REQUEST dispatch, for example, as a result of calling sendError on the response. In that case we are still in the filter chain, on the same thread, but the request and response have been switched to the original, unwrapped ones.

      Sub-classes may use this method to filter such nested ERROR dispatches and re-apply wrapping on the request or response. ThreadLocal context, if any, should still be active as we are still nested within the filter chain.

      Overrides:
      doFilterNestedErrorDispatch in class OncePerRequestFilter
      Throws:
      jakarta.servlet.ServletException
      IOException