DEV Community

Anh Trần Tuấn
Anh Trần Tuấn

Posted on • Originally published at tuanh.net on

Handling the "Forwarded" Header in Spring Boot Applications

1. Understanding the Forwarded Header

Image

The Forwarded header provides information about the original request, such as the originating protocol, client IP address, and host. This is useful for preserving the client’s information when a request traverses through intermediaries like proxies or load balancers.

1.1 Why is Handling Forwarded Important?

When your application is behind a load balancer or a reverse proxy, the incoming request details such as the IP address and protocol (HTTP/HTTPS) can get altered. Proper handling of Forwarded headers ensures the application receives the accurate client information. This is critical for:

  • Security : Properly configuring Forwarded headers can prevent potential IP spoofing.
  • Logging and Monitoring : Accurate logging for auditing and tracing the source of requests.
  • Application Behavior : Ensures the application behaves correctly based on the original request protocol and IP.

1.2 What Does the Forwarded Header Look Like?

The Forwarded header can contain several parameters:

Forwarded: for=192.0.2.43, for=198.51.100.17; proto=http; host=example.com
Enter fullscreen mode Exit fullscreen mode

1.3 Alternatives to Forwarded

Besides the Forwarded header, there are other headers such as X-Forwarded-For , X-Forwarded-Proto , X-Forwarded-Host , and X-Forwarded-Port which are used for similar purposes but are considered non-standard.

2. Configuring Spring Boot to Handle Forwarded Headers

Spring Boot provides various mechanisms to handle the Forwarded header. Below, we will explore how to configure Spring Boot to properly interpret and use the Forwarded header.

2.1 Enabling Forwarded Header Support in Spring Boot

By default, Spring Boot is capable of handling Forwarded headers if the application is behind a proxy. You can enable this support using the application.properties file:

server.forward-headers-strategy=native
Enter fullscreen mode Exit fullscreen mode

This configuration tells Spring Boot to use the native handling of Forwarded headers, which ensures compliance with the RFC 7239 specification.

2.2 Configuring with ForwardedHeaderFilter

Spring Boot provides a ForwardedHeaderFilter that can be configured as a bean in your application to handle the Forwarded headers more explicitly:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.filter.ForwardedHeaderFilter;

@Configuration
public class AppConfig {
    @Bean
    public ForwardedHeaderFilter forwardedHeaderFilter() {
        return new ForwardedHeaderFilter();
    }
}
Enter fullscreen mode Exit fullscreen mode

By adding this filter, Spring Boot will use the information from the Forwarded header to modify the request’s remote address, scheme, and host.

2.3 Example: Using Forwarded Header for Logging Client IP

Here’s an example of how to retrieve and log the client’s IP address using the Forwarded header in a Spring Boot application:

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ClientInfoController {

    @GetMapping("/client-info")
    public String getClientInfo(@RequestHeader(value = "Forwarded", required = false) String forwardedHeader) {
        if (forwardedHeader != null) {
            // Extract and log the "for" field from the Forwarded header
            String clientIp = forwardedHeader.split(";")[0].split("=")[1];
            System.out.println("Client IP: " + clientIp);
            return "Client IP retrieved: " + clientIp;
        } else {
            return "No Forwarded header present";
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

When you run the above code and access the /client-info endpoint through a proxy that sets the Forwarded header, you should see the client’s IP address logged on the console.

3. Advanced Configuration for Forwarded Headers

In some cases, more advanced configuration is necessary, especially in complex deployment environments involving multiple proxies or load balancers.

3.1 Using Tomcat with Spring Boot

If you are using an embedded Tomcat server in Spring Boot, you might want to configure the RemoteIpValve for more sophisticated Forwarded header handling:

server.tomcat.remote-ip-header=x-forwarded-for
server.tomcat.protocol-header=x-forwarded-proto
Enter fullscreen mode Exit fullscreen mode

3.2 Custom Filter for Complex Scenarios

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.annotation.WebFilter;
import java.io.IOException;

@WebFilter("/custom-filter")
public class CustomForwardedFilter implements Filter {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        // Custom logic to handle Forwarded header
        String forwarded = request.getHeader("Forwarded");
        if (forwarded != null) {
            System.out.println("Handling custom forwarded logic: " + forwarded);
        }
        chain.doFilter(request, response);
    }

    @Override
    public void init(FilterConfig filterConfig) {
    }

    @Override
    public void destroy() {
    }
}
Enter fullscreen mode Exit fullscreen mode

Deploy the above filter in your Spring Boot application and observe how requests are handled based on the Forwarded header. The filter will execute custom logic whenever a request is made to /custom-filter.

4. Conclusion

Handling the Forwarded header in Spring Boot applications is critical for maintaining security, ensuring proper logging, and supporting correct application behavior in proxy environments. By following the techniques discussed in this article, you can ensure your application properly processes and utilizes the Forwarded header.

If you have any questions or need further clarification, feel free to comment below!

Read posts more at : Handling the "Forwarded" Header in Spring Boot Applications

Top comments (0)