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



I have a Spring Boot application deployed in AWS Elastic Beanstalk.

For one of my APIs, I am need to check the client hostname address.

I am using

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

(where request is a HttpServletRequest).

I know that the HTTP spec and the Java servlet spec both say that both of these values may be absent. However, I am seeing that each time the value for both is “127.0.0.1”.

I assume that the way Elastic Beanstalk is set up, all requests to the VM come from within. Is there a way to retrieve the client address header from within?

If I use CloudFront for HTTPS termination, is there a way to have it pass the client address through?

Answer

The basic answer to the question is that AWS Elastic Beanstalk gets requests via a local proxy. CloudFront also acts as a reverse proxy.

The solution is to use the X-Forwarded-For header on the request.

This is a de-facto standard header used by HTTP proxy servers.

This is a multi-value header – populated by each proxy along the way. The first entry is the actual remote client address. Subsequent values are for proxy hosts.

request.getHeader("X-Forwarded-For") will give you the raw value.

request.getHeaders("X-Forwarded-For") will give you an Enumeration<String>[1], which you can iterate through to get individual values.

[1] Enumeration is an interface – the most common implementation of which is a Vector. Iterate as follows

Enumeration<String> headers = ...;

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


Source: stackoverflow