【问题标题】:"X_FORWARDED_FOR" Header Doesn't Present In The Request请求中不存在“X_FORWARDED_FOR”标头
【发布时间】:2012-12-09 14:27:23
【问题描述】:

在我的 Web 应用程序中,我需要为代理后面的客户端提取真实 IP 地址,经过搜索我发现可能的方法是读取“X_FORWARDED_FOR”标头的内容,我使用的是 java servlet 和标头传入的请求不包含“X_FORWARDED_FOR”标头,那么为什么标头不包含在请求中?

我正在使用 java 1.7、tomcat v7、代理服务器 :TMG 并配置为使用“X_FORWARDED_FOR”标头。

请指教。

提前致谢。

更新:

  • 请求来自 jquery ajax 请求到 servlet。
  • 我读取可用标题的代码:

    String ip = request.getHeader("X-Forwarded-For"); //返回null

            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {  
                ip = request.getHeader("Proxy-Client-IP");  //return null
            }  
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {  
                ip = request.getHeader("WL-Proxy-Client-IP");  //return null
            }  
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {  
                ip = request.getHeader("HTTP_CLIENT_IP");  //return null
            }  
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {  
                ip = request.getHeader("HTTP_X_FORWARDED_FOR");  //return null
            }  
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {  
                ip = request.getRemoteAddr();  //return proxy server IP
            }  
    

【问题讨论】:

  • 请求从何而来?远非所有代理都会添加X_FORWARDED_FOR。另外:您可以将阅读标题的相关代码片段添加到您的问题中吗?
  • 这不是编程问题。它可能适用于服务器故障。该请求没有标头,因为客户端没有添加它,无论该客户端是代理服务器还是浏览器。
  • @erickson 看起来代码有一个错误,这就是它无法工作的原因,那么为什么这不是一个编程问题呢?
  • @eis 我没有看到这个错误。如果是这样的话,这确实是这个地方。我从表面上接受了他的问题:如果请求不包含标头,那是客户端,而不是代码。
  • 我在 serverfault.com 中询问过,这就是解决方案:serverfault.com/questions/456532/…

标签: java tomcat proxy


【解决方案1】:

X-Forwarded-For 以及您测试的其他标头是自定义的(它是 almost standard,但不完全是)。代理不必设置任何此类标头,因此您必须测试代理服务器将设置哪个标头(如果有)。

但是,如果要设置它,您将使用它进行测试

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

HTTP_X_FORWARDED_FOR 将是 PHP 命名,如果您不使用 PHP,请不要使用它...

我会迭代所有传入的标头并查看是否有任何标头包含 ip。如果他们都没有,那你就不走运了。

您可以使用

迭代所有标题
enames = request.getHeaderNames();
while (enames.hasMoreElements()) {
  String name = (String) enames.nextElement();
  String value = request.getHeader(name);
  // "name" and "value" variables contain the header + its value
}

另请注意,对于 java 应用程序,通常传递给 servlet 的是内部请求,您需要先请求外部请求才能获取具有标头的 httpservletrequest 实例。

还要注意,即使您实际上从该标头中获得了一个 ip,您仍然应该考虑这是否是可用的信息。有关它的更多详细信息here

【讨论】:

  • @ChristofferHammarström 正确。我的答案中有相同的维基百科链接,但在编写代码示例时仍然在思考错误的方式......谢谢
【解决方案2】:

这可能有效:

 public static String X_FORWARDED_FOR_HEADER = "X-Forwarded-For";

 public static boolean isNullOrEmpty(String val) 
  {
    if (val == null || val.length() == 0) 
    {
      return true;
    }
    return false;
  } 

 public static String getRemoteAddress(HttpServletRequest request) {
  String remoteAddr = request.getHeader(X_FORWARDED_FOR_HEADER);
  if (!isNullOrEmpty(remoteAddr)) {
      int pos = remoteAddr.indexOf(',');
      if (pos < 0) {
          return remoteAddr;
      }
      return remoteAddr.substring(0,pos); // if more then 1, take first one 
  }
  return request.getRemoteAddr();
  }

【讨论】:

    猜你喜欢
    • 2021-02-21
    • 2019-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-20
    • 2015-01-25
    • 2018-06-08
    相关资源
    最近更新 更多