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