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