如何从 Elastic Beanstalk 中的 Spring Boot 应用程序中获取客户端主机名和/或客户端 IP 地址?

Posted

技术标签:

【中文标题】如何从 Elastic Beanstalk 中的 Spring Boot 应用程序中获取客户端主机名和/或客户端 IP 地址?【英文标题】:How do I get the Client Hostname and/or client IP address from within a Spring Boot application in Elastic Beanstalk? 【发布时间】:2021-02-11 00:52:57 【问题描述】:

我在 AWS Elastic Beanstalk 中部署了一个 Spring Boot 应用程序。

对于我的一个 API,我需要检查客户端主机名地址。

我正在使用

String ipAddress = request.getRemoteAddr();
String hostname = request.getRemoteHost();

(其中requestHttpServletRequest)。

我知道 HTTP 规范和 Java servlet 规范都说这两个值都可能不存在。但是,我看到每次 both 的值都是“127.0.0.1”。

我假设 Elastic Beanstalk 的设置方式,对 VM 的所有请求都来自内部。 有没有办法从内部检索客户端地址标头?

如果我使用 CloudFront 进行 HTTPS 终止,有没有办法让它通过客户端地址?

【问题讨论】:

这能回答你的问题吗? How to cope with x-forwarded-headers in Spring Boot 2.2.0? (Spring Web MVC behind reverse proxy) 还是这个? Elastic Load Balancer not passing X-Forwarded-For in Beanstalk app 还是这个? Retrieving CloudFront-Forwarded-Proto with php 【参考方案1】:

这个问题的基本答案是 AWS Elastic Beanstalk 通过本地代理获取请求。 CloudFront 还充当反向代理。

解决方案是在请求上使用X-Forwarded-For 标头。

这是 HTTP 代理服务器使用的事实上的标准标头。

这是一个多值标头 - 沿途由每个代理填充。第一项是实际的远程客户端地址。后续值用于代理主机。

request.getHeader("X-Forwarded-For") 会给你原始值。

request.getHeaders("X-Forwarded-For") 会给你一个Enumeration<String>[1],你可以遍历它来获得单独的值。

[1] Enumeration 是一个接口——最常见的实现是Vector。如下迭代

Enumeration<String> headers = ...;

while (headers.hasMoreElements()) 
  String header =  headers.nextElement();
  // TODO: process header ...

【讨论】:

以上是关于如何从 Elastic Beanstalk 中的 Spring Boot 应用程序中获取客户端主机名和/或客户端 IP 地址?的主要内容,如果未能解决你的问题,请参考以下文章

如何从 aws-sdk 中的 s3 存储桶创建 Elastic Beanstalk 实例?

从 VPC 中的 Elastic Beanstalk 实例访问 RDS

如何从 Elastic Beanstalk 中的 Spring Boot 应用程序中获取客户端主机名和/或客户端 IP 地址?

将 AMI 映像用于 Elastic Beanstalk

AWS Elastic Beanstalk - .ebextensions

如何将烧瓶应用程序发送到 AWS Elastic Beanstalk?