【问题标题】:How to let Spring Cloud Gateway to forward the real client address to services如何让 Spring Cloud Gateway 将真实的客户端地址转发给服务
【发布时间】:2022-07-28 20:47:49
【问题描述】:

我第一次尝试构建自己的 Spring Cloud 应用程序。
我的 Spring Cloud Gateway(SCG 从现在开始)就在 nginx 后面。
SCG 将来自 nginx 的请求中继到我的 Eureka 服务器。
而我的 Eureka 客户最终会收到这些请求。

问题是,当 Eureka 客户端服务之一尝试提取
原始客户端的 IP 地址如下所示,检索到的地址是正在运行的主机
nginx,而不是客户端的。

@ResponseBody
public ResponseEntity<?> controllerMethod (
        @RequestBody MyDto myDto
        , HttpServletRequest request
) throws Exception {
   String clientAddress = null;
   if (Strings.isBlank(request.getHeader("X-Forwarded-For")) == true) {
       clientAddress = request.getHeader("X-FORWARDED-FOR");

       if (Strings.isBlank(clientAddress) == true) {
          clientAddress = request.getRemoteAddr();
       }
   }
   // ...
}

所以我尝试了下面提到的另一个线程描述的解决方法,
但它似乎对我不起作用。

https://stackoverflow.com/a/67018627/2318920

我尝试应用 Spring 官方参考文档中的指南,
https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#modifying-the-way-remote-addresses-are-resolved 我无法想象示例中整个 GatewayConfig.java 文件的样子。

因此,我写了我的GatewayConfig.java,如下所示。

package root.project.path.config;

import java.net.InetSocketAddress;

import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;
import org.springframework.cloud.gateway.support.ipresolver.XForwardedRemoteAddressResolver;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.server.ServerWebExchange;

import reactor.core.publisher.Mono;


@Configuration
public class GatewayConfig implements KeyResolver {

    @Bean
    @Override
    public Mono<String> resolve(ServerWebExchange exchange) {
        XForwardedRemoteAddressResolver resolver = XForwardedRemoteAddressResolver.maxTrustedIndex(1);
        InetSocketAddress inetSocketAddress = resolver.resolve(exchange);
        return Mono.just(inetSocketAddress.getAddress().getHostAddress());
    }
    
}   // END: public class GatewayConfig

然后我启动我的 SCG 服务,它会打印如下错误消息并停止。

Jul 27 20:21:33 account gateway[2219027]: ***************************
Jul 27 20:21:33 account gateway[2219027]: APPLICATION FAILED TO START
Jul 27 20:21:33 account gateway[2219027]: ***************************
Jul 27 20:21:33 account gateway[2219027]: Description:
Jul 27 20:21:33 account gateway[2219027]: Parameter 0 of method resolve in root.project.path.config.GatewayConfig required a bean of type 'org.springframework.web.server.ServerWebExchange' that could not be found.
Jul 27 20:21:33 account gateway[2219027]: Action:
Jul 27 20:21:33 account gateway[2219027]: Consider defining a bean of type 'org.springframework.web.server.ServerWebExchange' in your configuration.

我想我误解了一些东西。但我无法找到它现在是什么。
请帮帮我。

【问题讨论】:

  • 事实上,这个问题与 SCG 无关。根据 Wireshark 嗅探到的数据包,我的 Eureka 客户端服务应用程序正确接收了 X-Forwarded-For 标头。但真正的问题是控制器方法中的HttpServletRequest 参数确实不包含X-Forwarded-For 标头。

标签: spring-boot nginx spring-cloud nginx-reverse-proxy spring-cloud-gateway


【解决方案1】:

我找到了原因。其实这个问题不是SCG出现的。

在与我的问题相同的设置下,Eureka 客户端服务中application.properties(或我的源代码树中的application.yml)的server.forward-headers-strategy 属性项设置为framework。将其替换为native后,控制器方法中的request.getHeader("X-Forwarded-For")部分开始返回终端客户端的IP地址。

虽然这不是 SCG 的问题(至少对我而言),但我希望这篇文章能帮助那些可能正在与这种相同症状苦苦挣扎的人?

【讨论】:

    猜你喜欢
    • 2021-07-05
    • 2011-07-19
    • 2023-03-30
    • 1970-01-01
    • 2020-02-04
    • 2022-11-08
    • 1970-01-01
    • 1970-01-01
    • 2021-10-09
    相关资源
    最近更新 更多