如何从 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();
(其中request
是HttpServletRequest
)。
我知道 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 地址?