如何从 Elastic Beanstalk 中的 Spring 引导应用程序中获取客户端主机名 and/or 客户端 IP 地址?

How do I get the Client Hostname and/or client IP address from within a Spring Boot application in Elastic Beanstalk?

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

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

我正在使用

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

(其中 requestHttpServletRequest)。

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

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

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

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

解决方案是在请求中使用 X-Forwarded-For header。

这是 HTTP 代理服务器使用的 de-facto 标准 header。

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

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 ...
}