Extracting the Client IP Chain from X-Forwarded-For Header in Spring Applications
Have you ever wondered how to identify the real client IP in a web application hosted behind multiple proxies? In today’s internet ecosystem, client requests often travel through several layers of reverse proxies, load balancers, or CDNs (e.g., A...

I am Tuanh.net. As of 2024, I have accumulated 8 years of experience in backend programming. I am delighted to connect and share my knowledge with everyone.
1. What is the X-Forwarded-For Header?
1.1 Overview of the Header
X-Forwarded-For: 192.168.1.10, 203.0.113.43, 198.51.100.1
- 192.168.1.10: The original client IP.
- 203.0.113.43: The IP of the first proxy.
- 198.51.100.1: The IP of the second proxy or load balancer.
1.2 Why It’s Important?
- Enhance security (e.g., IP whitelisting, rate-limiting).
- Provide geo-location-based services.
- Debug client-specific issues.
2. How to Extract Client IP Chain in Spring?
2.1 Setting Up a Custom Filter
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
@Component
public class ClientIpFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
String xForwardedFor = httpRequest.getHeader("X-Forwarded-For");
if (xForwardedFor != null) {
List<String> ipChain = Arrays.asList(xForwardedFor.split(","));
System.out.println("Client IP Chain: " + ipChain);
} else {
System.out.println("X-Forwarded-For header is missing");
}
chain.doFilter(request, response);
}
}
- Header Parsing: The X-Forwarded-For header is extracted using httpRequest.getHeader().
- IP Chain Splitting: The header value is split by commas to extract the chain of IPs.
- Logging: The resulting list of IPs is logged.
2.2 Configuring the Application
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class FilterConfig {
@Bean
public FilterRegistrationBean<ClientIpFilter> clientIpFilter() {
FilterRegistrationBean<ClientIpFilter> registrationBean = new FilterRegistrationBean<>();
registrationBean.setFilter(new ClientIpFilter());
registrationBean.addUrlPatterns("/*"); // Apply to all endpoints
return registrationBean;
}
}
3. Handling Edge Cases
3.1 Missing or Malformed Header
String xForwardedFor = httpRequest.getHeader("X-Forwarded-For");
String clientIp = (xForwardedFor != null) ? xForwardedFor.split(",")[0] : request.getRemoteAddr();
System.out.println("Client IP: " + clientIp);
3.2 Handling Trust Levels
List<String> trustedProxies = List.of("198.51.100.1", "203.0.113.43");
List<String> ipChain = Arrays.asList(xForwardedFor.split(",")).stream()
.filter(ip -> !trustedProxies.contains(ip.trim()))
.toList();
4. Advanced Scenarios
4.1 Logging IP Chains for Analytics
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
private static final Logger logger = LoggerFactory.getLogger(ClientIpFilter.class);
logger.info("Client IP Chain: {}", ipChain);
4.2 Securing the Header
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
5. Best Practices
X-Forwarded-For: 192.168.1.10, 203.0.113.43
6. Conclusion
Read more at : Extracting the Client IP Chain from X-Forwarded-For Header in Spring Applications





