Spring中如何获取X-Forwarded-For头的完整IP地址列表?
如何获取完整的X-Forwarded-For IP地址链(Spring Boot 3.x/Spring Framework 6.x)
核心结论
Spring 官方的ForwardedHeaderUtils设计初衷是提取最终客户端IP(即X-Forwarded-For头中的第一个IP),并没有直接提供获取完整IP链的内置工具。想要拿到完整的转发IP列表,需要手动解析X-Forwarded-For头,但可以借助Spring的工具类简化处理。
实现方案
1. Servlet环境下的解析
直接从HttpServletRequest中获取完整的X-Forwarded-For头值,利用Spring的StringUtils分割并清理IP格式:
import org.springframework.util.StringUtils; import jakarta.servlet.http.HttpServletRequest; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.stream.Collectors; public List<String> getFullForwardedIpChain(HttpServletRequest request) { String forwardedForHeader = request.getHeader("X-Forwarded-For"); if (!StringUtils.hasText(forwardedForHeader)) { return Collections.emptyList(); } // 分割头内容,自动处理逗号分隔符,同时清理每个IP的前后空格 String[] ipSegments = StringUtils.tokenizeToStringArray(forwardedForHeader, ","); return Arrays.stream(ipSegments) .map(String::trim) .filter(StringUtils::hasText) .collect(Collectors.toUnmodifiableList()); }
2. WebFlux环境适配
如果是响应式WebFlux场景,从ServerHttpRequest中获取头信息,逻辑与Servlet环境一致:
import org.springframework.util.StringUtils; import org.springframework.http.server.reactive.ServerHttpRequest; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.stream.Collectors; public List<String> getFullForwardedIpChain(ServerHttpRequest request) { String forwardedForHeader = request.getHeaders().getFirst("X-Forwarded-For"); if (!StringUtils.hasText(forwardedForHeader)) { return Collections.emptyList(); } String[] ipSegments = StringUtils.tokenizeToStringArray(forwardedForHeader, ","); return Arrays.stream(ipSegments) .map(String::trim) .filter(StringUtils::hasText) .collect(Collectors.toUnmodifiableList()); }
关于Spring内置组件的说明
Spring提供的ForwardedHeaderFilter或ForwardedHeaderTransformer等组件,核心作用是重构请求的远程地址(将X-Forwarded-For的第一个IP设为请求的remoteAddr),并不能直接获取完整的IP链。这些组件主要用于让Spring应用感知真实客户端IP,而非暴露整个转发链路。
最佳实践
- 清理格式:X-Forwarded-For的常见格式是
ip1, ip2, ip3(逗号后带空格),必须对每个IP段做trim处理。 - 过滤无效值:处理头末尾带逗号或空值的情况,避免出现空字符串元素。
- 不可变集合:返回
toUnmodifiableList()避免后续代码意外修改IP链数据。
内容的提问来源于stack exchange,提问作者Huseyin Aydin
相关产品推荐
相关产品推荐

