spring-cloud/spring-cloud-gateway

No X-Forwarded-For (RemoteIP) header is written due to incompatibility between XForwardedHeadersFilter and ForwardedHeadersTransformer

开放

#2,648 创建于 2022年6月22日

 (8 条评论) (0 个反应) (0 位负责人)Java (3,204 个派生)batch import
bughelp wanted

仓库指标

星标
 (4,284 个星标)
PR 合并指标
 (PR 指标待抓取)

描述

Describe the bug If ForwardedHeaderTransformer is enabled in Spring Cloud Gateway, X-Forwarded-For Header will not be sent to upstream services

Steps to reproduce

  • Enable ForwardedHeaderTransformer in Spring Cloud Gateway by setting: server.forward-headers-strategy=framework
  • Setup some upstream service to which the gateway fowards requests.
  • Use a REST client to send some request to the upstream service via gateway. Set the X-Forwarded-For header in the request.
  • Watch the request going to the upstream service. It has no X-Forwarded-For header.
  • Other headers, like X-Forwarded-Host will work.

Debugging

Since a while, ForwardedHeaderTransformer in Spring Boot supports X-Forwarded-For header:

remoteAddress = UriComponentsBuilder.parseForwardedFor(request, remoteAddress);

In UriComponentsBuilder.parseForwardedFor, the address is build as following:

return InetSocketAddress.createUnresolved(host, port);

However, in Spring Cloud Gateway, we have the following in XForwardedHeadersFilter:

if (isForEnabled() && request.getRemoteAddress() != null
				&& request.getRemoteAddress().getAddress() != null) {
			String remoteAddr = request.getRemoteAddress().getAddress().getHostAddress();
			write(updated, X_FORWARDED_FOR_HEADER, remoteAddr, isForAppend());
		}

Debugging shows, that request.getRemoteAddress().getAddress() is null and so, no X-Fowarded-For Header is written. I guess that is due to the InetSocketAddress.createUnresolved in UriComponentsBuilder.

I don't know whether ForwardedHeaderTransformer / UriComponentsBuilder or XForwardedHeadersFilter is wrong here, but together, they fail.

P.S.: createUnresolved seems to be intentionally, to avoid DNS resolution. See https://github.com/spring-projects/spring-framework/commit/c5ac8e8ab62cf7a616d5316bc6ef6d5d5e461c10 So, it would probably be the best solution if XForwardedHeadersFilter could (also) deal with an unresolved remote address.

贡献者指南