2011-01-13 8 views
53

Gibt es eine Möglichkeit, die ursprüngliche IP-Adresse des Clients auf dem Server zu erhalten? Ich kann request.getRemoteAddr() verwenden, aber ich scheint immer die IP des Proxy oder des Webservers zu bekommen.Wie bekomme ich die Remote-Adresse eines Clients in Servlet?

Ich möchte die IP-Adresse wissen, die der Client verwendet, um mich zu verbinden. Gibt es das überhaupt, dass ich es bekommen könnte?

Antwort

8

request.getRemoteAddr() ist der Weg. Es scheint, dass Ihr Proxy die Quell-IP ändert. Wenn einige Proxies das tun, fügen sie die ursprüngliche IP in irgendeinem benutzerdefinierten HTTP-Header hinzu. Verwenden Sie request.getHeaderNames() und request.getHeaders(name) und drucken Sie alle von ihnen, um zu sehen, ob es nichts von Interesse gibt. Wie X-CLIENT-IP (gemacht, dass man oben, aber sie sehen so aus)

+0

Dank, werde ich die Header überprüfen .... obwohl, wenn es über einen Webserver zum Beispiel passiert, ich den Webserver erhalten dann Adresse – grassbl8d

+2

Sie request.getHeaderNames bedeuten Sie()? – theyuv

4

Sie können dies nicht in einer sinnvollen Weise tun.

Der Proxy kann einen Proxy-for-Header hinzufügen oder auch nicht, aber in vielen Fällen wird dies nur eine interne Adresse sein, so dass es für Sie bedeutungslos ist. Die meisten Proxys am Rande einer Organisation sind so konfiguriert, dass sie so wenig wie möglich über die Interna des Netzwerks offenbaren.

Worauf möchten Sie diese Informationen anwenden?

+0

gut, ich bin Art erforderlich, um die Adresse der Benutzer anmelden, die zugreifen. Sie haben Recht, einige Proxies es zu entfernen scheinen, und ich habe oft den Proxy ihn zu ersetzen .... Ich denke mir, ob ich vielleicht von der SSL-Sitzung einige Informationen bekommen konnte – grassbl8d

88

versuchen Sie dies:

public static String getClientIpAddr(HttpServletRequest request) { 
     String ip = request.getHeader("X-Forwarded-For"); 
     if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { 
      ip = request.getHeader("Proxy-Client-IP"); 
     } 
     if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { 
      ip = request.getHeader("WL-Proxy-Client-IP"); 
     } 
     if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { 
      ip = request.getHeader("HTTP_CLIENT_IP"); 
     } 
     if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { 
      ip = request.getHeader("HTTP_X_FORWARDED_FOR"); 
     } 
     if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { 
      ip = request.getRemoteAddr(); 
     } 
     return ip; 
    } 
+0

Ist es in Ordnung, in diesem Fall statt, wenn conditiona verwendet von if/else? – Andrew

+1

ja, weil wir überprüfen müssen, ob der vorherige Vorgang erfolgreich ist oder nicht, möglicherweise do-while wäre besser –

+1

X-Forwarded-For kann mehr als eine IP-Adresse enthalten. – dmatej

0
String ipAddress = request.getHeader("x-forwarded-for"); 
     if (ipAddress == null) { 
      ipAddress = request.getHeader("X_FORWARDED_FOR"); 
      if (ipAddress == null){ 
       ipAddress = request.getRemoteAddr(); 
      } 
     } 
0

"x-forwarded-for" Request-Header IP die ursprüngliche Client enthält, wenn ein Proxy oder einen Load Balancer verwenden. Aber ich denke nicht alle Proxies/lb fügt diesen Header hinzu.

Hier einige Java-Code den Header zu analysieren: http://www.codereye.com/2010/01/get-real-ip-from-request-in-java.html

Wenn dieser Header nicht vorhanden ist, dann würde ich gehen Sie wie @Bozho schlägt

4

Die beste Lösung, die ich jemals

verwendet habe
public String getIpAddr(HttpServletRequest request) {  
    String ip = request.getHeader("x-forwarded-for");  
    if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {  
     ip = request.getHeader("Proxy-Client-IP");  
    }  
    if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {  
     ip = request.getHeader("WL-Proxy-Client-IP");  
    }  
    if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {  
     ip = request.getRemoteAddr();  
    }  
    return ip;  
} 
3

Da dies in der Regel ein Problem bei der Bereitstellung und nicht bei der Anwendung ist, wäre ein anderer Ansatz, den Anwendungscontainer entsprechend zu konfigurieren. Einmal konfiguriert, nimmt der Behälter darauf, den entsprechenden Header des Prüfens und Ihre Anwendung weiterhin request.getRemoteAddr() verwenden.

Zum Beispiel können Sie in Tomcat die Remote IP Valve verwenden. Ich würde annehmen, dass die meisten Anwendungsserver eine ähnliche Funktionalität haben.

Der Behälter könnte auch um Verständnis nehmen, wenn Ihr Front-End-Load-Balancer ist SSL-Verbindungen beendet wird, die Anforderung an den App-Server über HTTP weitergeleitet werden. Dies ist wichtig, wenn Ihre Anwendung URLs für sich selbst generieren muss.

-5
InetAddress inetAddress = InetAddress.getLocalHost(); 
String ip = inetAddress.getHostAddress(); 
+0

Dies gibt nur die IP des lokalen Hosts. –