I have an app engine application that runs REST web services.
I want to extract the ip address from all requests that are handled by my web services.
from javax.servlet.http.HttpServletRequest i'm trying to extract the ip address checking the "X-Real-IP" , if empty or "unknown" check the first ip in the list of "X-Forwarded-For" header if empty or "unknown" get it from request.getRemoteAddr().
I thought i covered all the cases but i'm still getting ip addresses like 10.x.x.x, or 127.0.0.1 or unknown.
I know that app engine applications are running behind load balancers, and instances are dynamic and i'm certainly omitting a header in the request cuz i can see the original ip address in the logs (from google) .
Edit : all the requests i'm working on are direct request to service (no queue or cron requests).
Any idea of the other headers to check ?
thx .
The answeres of this Question might help you. There are a lot of headers to check for:
private static final String[] HEADERS_TO_TRY = {
"X-Forwarded-For",
"Proxy-Client-IP",
"WL-Proxy-Client-IP",
"HTTP_X_FORWARDED_FOR",
"HTTP_X_FORWARDED",
"HTTP_X_CLUSTER_CLIENT_IP",
"HTTP_CLIENT_IP",
"HTTP_FORWARDED_FOR",
"HTTP_FORWARDED",
"HTTP_VIA",
"REMOTE_ADDR" };
Related
In my web-app I need to register http clients accessing from a local network behind a router.
I started with remoteHost : remotePort combination, but soon enough it became clear, that the port numer gets regenereated upon each connection.
I need to be able to identify the clients on something similar to MAC address, some property that doesn't change. I wanted to use headers[ "X-Forwarded-For" ], but it's not present at all:
[Pragma=no-cache, Cache-Control=no-cache, Host=somhost.com:8822, Upgrade=websocket, Connection=Upgrade, Sec-WebSocket-Key=scnlM7hzjjy3cklJhJciA==, Sec-WebSocket-Extensions=x-webkit-deflate-frame,deflate-frame, Sec-WebSocket-Version=13]
What are the other options to identify clients?
You could use an API key, that is, a unique identifier that the clients send along with each request to identify themselves. Depending on the authentication method you are using, you could consider the standard HTTP Authorization header to send this value:
Authorization: API-Key <value goes here>
Or create a custom HTTP header for this purpose. But be careful with custom headers: proxies might strip them out.
One option is using cookies. As the client accesses the webapp for the first time we could set a cookie on the client side that has a very long expiry date.
During the subsequent user re-logins we can rely on this cookie as cookies get sent to the server.
You can try this bit of PHP to see what the server knows about an incoming http request:
$keys = array_keys($_SERVER);
echo "<table bgcolor='black' cellpadding='1' cellspacing='1'>\n";
echo " <tr bgcolor='yellow'><td><b>Key</b></td><td><b>Value</b></td></tr>\n";
foreach ($keys as $key) {
echo " <tr bgcolor='white'><td>" . $key . "</td><td>" . $_SERVER[$key] . "</td></tr>\n";
}
echo "</table>\n";
Are you identifying the user at the keyboard or the device making the request? Do you need to track these long term or only for the duration of a use session? Do your users connect from multiple devices?
Client side id certificates could work, depending on how the local machines are managed. If they are accessing your app from someplace they've already authenticated, then setting up a single sign on solution could work. Prompting for authentication always works too.
I have a Spring Boot (MVC) java server. How can I track each unique Web request? For example, I'd like to know the following.
How to get user agent of Web request (browser type, device such as mobile or desktop)
How to get the IP address or location of the Web request?
How to count number of Web request? For examppe, I'd like to count the request count in a synchronized fashion.
Most of the things will be given by HttpServletRequest, using headers.
1. How to get user agent of Web request
User agent ? Exactly !
String userAgentInfo = request.getHeader("User-Agent");
also there is an API as utils to check the information.
2. How to get the IP address or location of the Web request?
Though I cannot point to the location information, we can get IP address information using varied headers.
X-Forwarded-For
Proxy-Client-IP
WL-Proxy-Client-IP
HTTP_X_FORWARDED_FOR
HTTP_X_FORWARDED
HTTP_X_CLUSTER_CLIENT_IP
HTTP_CLIENT_IP
HTTP_FORWARDED_FOR
HTTP_FORWARDED
HTTP_VIA
REMOTE_ADDR
Depending on the request type these can give you IP information.
3. How to count number of Web request?
Old fashioned Filter creation will help you in tracking the hit counts.
This can help you better.
If Spring-boot is the catch, the implementation is bit change in getting the values,
In the controller, using #RequestHeader(value="User-Agent") can help. Similarly for the others too.
i am having some issues and almost no documentation on internet about id session tokens and Java web services. We have a server (Tomcat providing web services on JAX-WS + SOAP) that is providing an API to query an SQL server.
I have to code a simple Java client that communicates with the server through this web services. The issue is that before being able to use any of its server WSDL methods, the client has to authenticate through a web server method where you send the user/pass, and the server gives back to client a session-id (alfanumeric string).
The rest of the methods do not have any kind of parameter where i can pass the session id, so i suppose it has to be used as a "context". I have found information about how in JAX-WS you can maintain session-id:
https://weblogs.java.net/blog/ramapulavarthi/archive/2006/06/maintaining_ses.html
Hello port = new HelloService().getHelloPort();
((BindingProvider)port).getRequestContext().put(BindingProvider.
SESSION_MAINTAIN_PROPERTY,true);
in my case, if i want to receive the cookie session-id, i have to:
org.tempuri.RUWebService service = new org.tempuri.RUWebService();
org.tempuri.RUWebServiceSoap myport = new org.tempuri.RUWebServiceSoap();
String session-id = myport.Auth(user,pass);
where the session-id is an UUID variable is a String of a hex variable: 8-4-4-4-8 .. that i can change to real hex like:
java.util.UUID uuidFromHyphens = java.util.UUID.fromString("6f34f25e-0b0d-4426-8ece-a8b3f27f4b63");
I tried the following code, where i change "port" variable to "myport", trying to match both examples:
((BindingProvider)myport).getRequestContext().put(BindingProvider.
SESSION_MAINTAIN_PROPERTY,true);
It compiles, but when i consult the web server through some of its methods, i receive a "null", the same as if i do not make the auth procedure. My issue i think is that i don't know what i am doing wrong with cookie session-id auth procedure.
If somebody could help me, i would be grateful.
regards.
Either you pass it as Request Parameter using GET or POST methods
(or)
Put the session id in outgoing HTTP header, like
GET / HTTP/1.0
Accept: text/plain
Accept: text/html
Session-Id:DFF55566_SOMEID
But for both of this to work, your web server must expect the Session Id from client in some format either at server level (or) your application level.
I'm working on project using Java, in which IP address will be identity of the client/user. So I'm facing one problem: where user can spoof their host identity, that can lead to false identity of the user. So, anyone know, how to detect whether the host is using proxy or not?
InetAddress thisIp = InetAddress.getLocalHost();
I'm using above code to detect the host IP address.
You cannot 100% reliably check this, but to cover the most proxies, you could check the presence of the X-Forwarded-For request header.
if (request.getHeader("X-Forwarded-For") != null) {
// Client is likely using a proxy.
}
There is no standard for this. Each proxy may have its own specific set of additional/custom headers. You could log the retrieved request headers and examine which headers are been set by certain proxies and then alter the code accordingly. Again, you cannot reliably check this. Some proxies may even have no additional headers at all. You'd need to maintain a list of IP addresses of "well known" proxies so that you can check getRemoteAddr() against it.
Unrelated to the concrete problem, as you tagged this with jsp, I would only add that writing Java code inside a JSP is a poor practice. You'd normally do this in a normal Java class like a servlet or a filter.
I'm writing a web application, I need to do a audit log for all the actions in the application. For this purpose I need to get the IP Address of the client systems.
I'm using request.getRemoteAddr() to get the remote IP Address. But this has a problem, if the client is behind a proxy this method will give the IP of the proxy system.
When I did some search I found a header attribute called 'X-FORWARDED-FOR' in the HttpRequest object.
Can somebody tell me how exactly this header property works and how can I used this header to get the IP address of the client system.
Thank you
getRemoteIP returns the remote IP address of the user (assuming all HTTP intermediaries are well behaved wrt XFF header).
String getRemoteIP(HttpServletRequest request) {
String xff = request.getHeader("X-Forwarded-For");
if (xff != null) {
return xff.split("[\\s,]+")[0];
}
return request.getRemoteAddr();
}
The client's proxy - typically a firewall or somesuch - will populate the x-forwarded-for header with the ip it receives from its client, which is typically, but is not required to be (in the case of a user going through multiple proxies or firewalls) the ip of the user's machine.
'X-FORWARDED-FOR' is used for identifying the originating/actual IP address of a client connecting to a web server through an HTTP proxy.
You can simply use the value for this attribute to find out the originating client IP, even if it's behind a proxy.