2013-04-23 6 views
29

Ich habe einige Probleme mit einem einfachen Problem. Ich würde die reale Klienten IP innerhalb eines HTTPServlet erhalten.Erhalten Sie echte Client-IP in einem Servlet

Da ich jetzt gebraucht:

request.getRemoteAddr() 

Aber jetzt gibt es eine falsche IP. zB: xxx.xxx.xxx. aber meine IP ist so etwas wie xxx.xxx.xxx. . (überprüft unter http://whatismyipaddress.com/).

Jetzt habe ich versucht, zu verwenden:

request.getHeader("X-Forwarded-For") 

Es NULL zurück.

Ich habe auch eine Sonde mit der folgenden Klasse:

public class IpUtils { 

public static final String _255 = "(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)"; 
public static final Pattern pattern = Pattern.compile("^(?:" + _255 + "\\.){3}" + _255 + "$"); 

public static String longToIpV4(long longIp) { 
    int octet3 = (int) ((longIp >> 24) % 256); 
    int octet2 = (int) ((longIp >> 16) % 256); 
    int octet1 = (int) ((longIp >> 8) % 256); 
    int octet0 = (int) ((longIp) % 256); 

    return octet3 + "." + octet2 + "." + octet1 + "." + octet0; 
} 

public static long ipV4ToLong(String ip) { 
    String[] octets = ip.split("\\."); 
    return (Long.parseLong(octets[0]) << 24) + (Integer.parseInt(octets[1]) << 16) 
      + (Integer.parseInt(octets[2]) << 8) + Integer.parseInt(octets[3]); 
} 

public static boolean isIPv4Private(String ip) { 
    long longIp = ipV4ToLong(ip); 
    return (longIp >= ipV4ToLong("10.0.0.0") && longIp <= ipV4ToLong("10.255.255.255")) 
      || (longIp >= ipV4ToLong("172.16.0.0") && longIp <= ipV4ToLong("172.31.255.255")) 
      || longIp >= ipV4ToLong("192.168.0.0") && longIp <= ipV4ToLong("192.168.255.255"); 
} 

public static boolean isIPv4Valid(String ip) { 
    return pattern.matcher(ip).matches(); 
} 

public static String getIpFromRequest(HttpServletRequest request) { 
    String ip; 
    boolean found = false; 
    if ((ip = request.getHeader("x-forwarded-for")) != null) { 
     StringTokenizer tokenizer = new StringTokenizer(ip, ","); 
     while (tokenizer.hasMoreTokens()) { 
      ip = tokenizer.nextToken().trim(); 
      if (isIPv4Valid(ip) && !isIPv4Private(ip)) { 
       found = true; 
       break; 
      } 
     } 
    } 

    if (!found) { 
     ip = request.getRemoteAddr(); 
    } 

    return ip; 
} 
} 

Es ist auch die xxx.xxx.xxx.50 IP zurückgegeben. :(

Nun weiß ich nicht, wie das reale Client-IP zu erhalten. Wenn jemand die Lösung weiß, bitte, eine Antwort machen.

+0

Ist Ihr Server mit dem Internet verbunden? Gibt es Router, Load Balancer, NAT-Geräte usw.? – mindas

+0

Es gibt nur einen Ruter. – TAR515

Antwort

27

Ich vermute, dass Ihr Problem ist, dass Sie Server irgendwo im lokalen Netzwerk ausführen, damit Sie Ihre IP in diesem Netzwerk erhalten. Wenn Sie jedoch versuchen, einen Onlinedienst zu verwenden, der Ihre IP-Adresse erkennt, ist Ihre IP die IP des Routers Ihres Diensteanbieters oder etwas Ähnliches. Die Verwendung von request.getRemoteAddr() ist korrekt. Dies ist, was solche Dienste tun, und sie haben keine anderen Einrichtungen.

+0

Mein Server (mit dem Servlet) und mein Client läuft auf demselben PC. Aber ich bekomme den localhost nicht als IP, weil der Client die echte IP verwendet, wenn er eine Verbindung zum Server herstellen würde. 188.xxx.xxx.158. Ich habe es seit jetzt benutzt und es hat perfekt funktioniert, das ist das erste Mal, wenn ich eine falsche IP bekomme. – TAR515

12

Wenn Sie NAT haben (Network Address Translation) Gerät vor Ihrem Servlet-Container request.getRemoteAddr() gibt die Adresse von NAT zurück, da sie eine neue Verbindung initiiert

Um Ihr Problem zu lösen, sollten Sie NAT konfigurieren, um die IP des ursprünglichen Clients in einer Kopfzeile zu senden. Dann, um die Kopfzeile von der Anforderung zu übernehmen Falls Sie in NAT X-Forwarded-For konfigurieren, verwenden Sie diesen Code: request.getHeader("X-Forwarded-For")

Ihre Funktion ist korrekt, Sie können sie verwenden, wenn Sie NAT konfigurieren.

+0

Ich benutze kein NAT-Gerät, wie ich weiß :) – TAR515

8

Java

String ip = request.getRemoteAddr(); 
if (ip.equalsIgnoreCase("0:0:0:0:0:0:0:1")) { 
    InetAddress inetAddress = InetAddress.getLocalHost(); 
    String ipAddress = inetAddress.getHostAddress(); 
    ip = ipAddress; 
} 
model.addAttribute("IP", ip); 

JSP <span><B>IP : <c:out value="${IP}" /></B></span> // Spring MAV 

JSP

<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> 
<%@ page import="java.net.InetAddress" %> 

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 
<html> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> 
<title>Displays Client IP Address</title> 
</head> 
<body> 
<% 
    // paste above java code 
out.println("<br><B>Clients IP : </B>"+ip); 
%> 
<span><br>Local Host : <%= request.getRemoteAddr() %></span> 
<span><br>ServerPort : <%= request.getServerPort() %></span> 
<span><br>Path  : <%= request.getRequestURI()%></span> 
</span> 
</body> 
</html> 

Wenn die jsp in lokalen Server bereitgestellt und diese jsp Zugriff auf 0 zurück: 0: 0: 0: 0: 0: 0 : 1. Wenn Sie mit ip lokal auf die Anwendung zugreifen, wird IP zurückgegeben.

RESTful Web Services mit Jersey

@javax.ws.rs.Path("/ip") 
public class GetIPInfo { 

    @GET @Produces(MediaType.TEXT_PLAIN) 
    public Response getIP(@Context javax.servlet.http.HttpServletRequest request) throws UnknownHostException { 

     String remoteHost = request.getRemoteHost(); 
     String remoteAddr = request.getRemoteAddr(); 
     if (remoteAddr.equals("0:0:0:0:0:0:0:1")) { 
      InetAddress localip = java.net.InetAddress.getLocalHost(); 
      remoteAddr = localip.getHostAddress(); 
      remoteHost = localip.getHostName(); 
     } 
     int remotePort = request.getRemotePort(); 

     String msgoutput = remoteHost + " (" + remoteAddr + " : " + remotePort + ")"; 
     return Response.status(200).entity(msgoutput).build(); 
    } 
} 

mit JavaScript direkt zu findenIP

Verwandte Themen