web-dev-qa-db-ja.com

クライアントのIPアドレスを取得する

JSPServlets(コンテナ:Glassfish)を使用してクライアントを取得する必要があるWebアプリケーションを開発していますIP Address

クライアントのIPアドレスを取得しています。これは、オフィスにあるコンピューターの一部のページ(顧客メンテナンスフォームなど)へのアクセスを許可するため、オフィス外のページへのアクセスを制限するためです。

これまでの私のコードは次のとおりです。

way1

String ipAddress =  request.getRemoteAddr();
System.out.println("IP Address: "+ipAddress);

way2

String ipAddress=null;
String getWay = request.getHeader("VIA");   // Gateway
ipAddress = request.getHeader("X-FORWARDED-FOR");   // proxy
if(ipAddress==null)
{
    ipAddress = request.getRemoteAddr();
}
System.out.println("IP Address: "+ipAddress);

上記のコードは、コンピューターを再起動するたびにdifferent IP Addressを提供します(シャットダウン->開始または再起動)。

私はIP6のようなものを得ています:

fe80:0:0:0:20ca:1776:f5ff:ff15%13

このコードの何が問題なのか教えてください。

41
Bhushan

@martinと この答え が説明したように、それは複雑です。クライアントのIPアドレスを取得する防弾の方法はありません。

できる最善の方法は、"X-Forwarded-For"を解析し、request.getRemoteAddr();に依存することです。

public static String getClientIpAddress(HttpServletRequest request) {
    String xForwardedForHeader = request.getHeader("X-Forwarded-For");
    if (xForwardedForHeader == null) {
        return request.getRemoteAddr();
    } else {
        // As of https://en.wikipedia.org/wiki/X-Forwarded-For
        // The general format of the field is: X-Forwarded-For: client, proxy1, proxy2 ...
        // we only want the client
        return new StringTokenizer(xForwardedForHeader, ",").nextToken().trim();
    }
}
68

次の静的ヘルパーメソッドを使用して、クライアントのIPを取得します。

public static String getClientIpAddr(HttpServletRequest request) {  
    String ip = request.getHeader("X-Forwarded-For");  
    if (ip == null || ip.length() == 0 || ip.equalsIgnoreCase("unknown")) {  
        ip = request.getHeader("Proxy-Client-IP");  
    }  
    if (ip == null || ip.length() == 0 || ip.equalsIgnoreCase("unknown")) {  
        ip = request.getHeader("WL-Proxy-Client-IP");  
    }  
    if (ip == null || ip.length() == 0 || ip.equalsIgnoreCase("unknown")) {  
        ip = request.getHeader("HTTP_X_FORWARDED_FOR");  
    }  
    if (ip == null || ip.length() == 0 || ip.equalsIgnoreCase("unknown")) {  
        ip = request.getHeader("HTTP_X_FORWARDED");  
    }  
    if (ip == null || ip.length() == 0 || ip.equalsIgnoreCase("unknown")) {  
        ip = request.getHeader("HTTP_X_CLUSTER_CLIENT_IP");  
    }  
    if (ip == null || ip.length() == 0 || ip.equalsIgnoreCase("unknown")) {  
        ip = request.getHeader("HTTP_CLIENT_IP");  
    }  
    if (ip == null || ip.length() == 0 || ip.equalsIgnoreCase("unknown")) {  
        ip = request.getHeader("HTTP_FORWARDED_FOR");  
    }  
    if (ip == null || ip.length() == 0 || ip.equalsIgnoreCase("unknown")) {  
        ip = request.getHeader("HTTP_FORWARDED");  
    }  
    if (ip == null || ip.length() == 0 || ip.equalsIgnoreCase("unknown")) {  
        ip = request.getHeader("HTTP_VIA");  
    }  
    if (ip == null || ip.length() == 0 || ip.equalsIgnoreCase("unknown")) {  
        ip = request.getHeader("REMOTE_ADDR");  
    }  
    if (ip == null || ip.length() == 0 || ip.equalsIgnoreCase("unknown")) {  
        ip = request.getRemoteAddr();  
    }  
    return ip;  
}
31
basZero

私はこれが好きです、試してみることができます

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;      
}   
7
coffee

BasZeroが述べたように、X-Forwarded-Forのコンマをチェックする必要があります。 (見てください: http://en.wikipedia.org/wiki/X-Forwarded-For )。このフィールドの一般的な形式は、X-Forwarded-For:clientIP、proxy1、proxy2 ...などです。そのため、X-FORWARDED-FOR:129.77.168.62、129.77.63.62のようなものが表示されます。

3
mkilic

ネットワークがどのように構成されているかにより関係があると思います。サーブレットは、見つけたアドレスを単に提供しています。

2つの回避策を提案できます。最初にIPV4を使用してみてください。こちらをご覧ください SO Answer

また、request.getRemoteHost()メソッドを使用してマシンの名前を取得してみてください。名前は、マップ先のIPに依存しません。

インフラストラクチャの担当者とこれについて議論する必要があると思います。

1
Raza