2011-01-13 17 views
53

Czy jest jakiś sposób, aby uzyskać oryginalny adres IP klienta przychodzącego na serwer? Mogę używać request.getRemoteAddr(), ale zawsze uzyskuję adres IP serwera proxy lub serwera WWW.Jak uzyskać adres zdalny klienta w serwlecie?

Chciałbym znać adres IP, z którego korzysta klient, aby się ze mną połączyć. Czy mimo to mogę to zdobyć?

Odpowiedz

8

request.getRemoteAddr() jest drogą. Wygląda na to, że twój serwer proxy zmienia źródłowy adres IP. Kiedy robią to niektóre proxy, dodają oryginalny adres IP w niestandardowym nagłówku http. Użyj request.getHeaderNames() ii wydrukuj wszystkie, aby sprawdzić, czy nie ma w nich żadnego zainteresowania. Tak jak X-CLIENT-IP (udało się to, ale wyglądają tak)

+0

dzięki, będę sprawdzać nagłówki .... chociaż kiedy przechodzi przez serwer WWW na przykład, a następnie uzyskać adres serwera WWW – grassbl8d

+2

Czy oznacza to request.getHeaderNames()? – theyuv

4

Nie możesz tego zrobić w sensowny sposób.

Serwer proxy może lub nie musi dodawać nagłówki proxy, ale w wielu przypadkach będzie to adres wyłącznie wewnętrzny, więc nie będzie dla ciebie bez znaczenia. Większość serwerów proxy znajdujących się na skraju organizacji jest skonfigurowana tak, aby w jak najmniejszym stopniu odsłonić wewnętrzne elementy sieci.

Do czego zamierzasz użyć tych informacji?

+0

cóż, jestem w pewnym stopniu zobowiązany do zarejestrowania adresu użytkowników, którzy uzyskują dostęp. masz rację, niektórzy pośrednicy zdają się go usuwać, a ja często zastępuję go proxy ... myślałem, czy mógłbym uzyskać jakieś informacje z sesji SSL – grassbl8d

88

spróbuj tego:

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

Czy to jest OK, w tym przypadku użyj, jeśli zamiast tego conditiona of/else? – Andrew

+1

tak, ponieważ musimy sprawdzić, czy poprzednia operacja zakończyła się sukcesem, czy nie, może użyć do-while byłoby lepiej –

+1

X-Forwarded-For może zawierać więcej niż jeden adres IP. – 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-przekazane-dla" nagłówka żądania zawiera oryginalnego klienta IP w przypadku korzystania z serwera proxy lub równoważenia obciążenia. Ale myślę, że nie wszystkie proxy/lb dodaje ten nagłówek.

Oto niektóre kodu Java do analizowania nagłówka: http://www.codereye.com/2010/01/get-real-ip-from-request-in-java.html

Jeśli nagłówek nie jest obecny wtedy będę postępować jak sugeruje @Bozho

4

Najlepszym rozwiązaniem, jakie kiedykolwiek używane

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

Ponieważ zazwyczaj jest to problem związany z wdrożeniem, a nie problemem związanym z aplikacją, innym rozwiązaniem byłoby odpowiednie skonfigurowanie kontenera aplikacji. Po skonfigurowaniu kontener zajmie się sprawdzeniem odpowiedniego nagłówka, a aplikacja będzie nadal używać request.getRemoteAddr().

Na przykład w Tomcat można użyć Remote IP Valve. Zakładam, że większość serwerów aplikacji ma podobną funkcjonalność.

Kontener może również zadbać o zrozumienie, czy frontowy równoważnik obciążenia kończy połączenia SSL, przekazując żądanie do serwera aplikacji za pośrednictwem protokołu HTTP. Jest to ważne, gdy aplikacja musi generować adresy URL.

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

To po prostu podaj adres IP lokalnego hosta. –