2011-01-13 8 views
53

C'è un modo per ottenere l'indirizzo IP originale del client che arriva al server? Posso usare request.getRemoteAddr(), ma mi sembra sempre di ottenere l'IP del proxy o del server web.Come posso ottenere l'indirizzo remoto di un client in servlet?

Vorrei conoscere l'indirizzo IP che il client sta utilizzando per connettersi a me. C'è comunque che potrei averlo?

risposta

8

request.getRemoteAddr() è il modo. Sembra che il tuo proxy cambi l'IP sorgente. Quando alcuni proxy fanno ciò aggiungono l'IP originale in qualche header http personalizzato. Usa request.getHeaderNames() e request.getHeaders(name) e stampale tutti per vedere se non c'è nulla di interessante. Come X-CLIENT-IP (fatto quello, ma assomigliano a questo)

+0

grazie, vado a controllare le intestazioni .... anche quando passa attraverso un server web, ad esempio, ho quindi ottenere l'indirizzo web server – grassbl8d

+2

Vuoi dire request.getHeaderNames()? – theyuv

4

Non è possibile farlo in modo significativo.

Il proxy può aggiungere o meno un'intestazione proxied-for, ma in molti casi questo sarà comunque solo un indirizzo interno, quindi non avrà alcun significato per voi. La maggior parte dei proxy al bordo di un'organizzazione sono configurati per rivelare il meno possibile sugli interni della rete.

Per cosa intendi utilizzare queste informazioni?

+0

beh, sono quasi obbligato a registrare l'indirizzo degli utenti che stanno accedendo. hai ragione, alcuni proxy sembrano rimuoverlo e spesso ho il proxy che lo sostituisce .... stavo pensando se potevo ottenere alcune informazioni dalla sessione SSL – grassbl8d

88

provare questo:

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

Va bene, in questo caso, usa se conditiona invece di se/else? – Andrew

+1

sì, perché è necessario verificare se l'operazione precedente ha esito positivo o meno, forse l'utilizzo di do-while sarebbe migliore. –

+1

X-Forwarded-For può contenere più di un indirizzo 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-inoltrato-per" intestazione di richiesta contenente il client originale IP se si utilizza un proxy o un bilanciatore di carico. Ma penso che non tutti i proxy/lb aggiungano questa intestazione.

Qui po 'di codice Java per analizzare l'intestazione: http://www.codereye.com/2010/01/get-real-ip-from-request-in-java.html

Se questa intestazione non è presente allora vorrei procedere come suggerisce @Bozho

4

La soluzione migliore che abbia mai usato

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

Poiché di solito questo è un problema di distribuzione, piuttosto che un problema di applicazione, un altro approccio sarebbe configurare il contenitore dell'applicazione in modo appropriato. Una volta configurato, il contenitore si occupa di ispezionare l'intestazione appropriata e l'applicazione continua a utilizzare request.getRemoteAddr().

Ad esempio, in Tomcat è possibile utilizzare lo Remote IP Valve. Presumo che la maggior parte dei server applicativi abbia funzionalità simili.

Il contenitore potrebbe anche comprendere se il servizio di bilanciamento del carico front-end sta terminando le connessioni SSL, inoltrando la richiesta al server delle app su HTTP. Questo è importante quando l'applicazione deve generare URL a se stessa.

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

Basta dare l'IP dell'host locale. –

Problemi correlati