休息 - 如何获取调用者的 IP 地址

Posted

技术标签:

【中文标题】休息 - 如何获取调用者的 IP 地址【英文标题】:Rest - how get IP address of caller 【发布时间】:2011-04-19 00:18:56 【问题描述】:

我正在编写 Java Rest Web 服务,需要调用者的 IP 地址。我以为我曾经在 cookie 中看到过这个,但现在我看不到了。是否有一致的地方可以获取这些信息?

我看到了一个使用“OperationalContext”来获取它的示例,但那不是在 java 中。

【问题讨论】:

欢迎来到 SO。我认为您需要添加 Java 标记来获得观众——这与 REST 无关 也许不直接与 Rest 相关,但肯定与 Web 服务相关(我对此也不太了解),不是吗?知道调用您的服务的 Web 客户端的 IP 地址不是休息/Web 服务的问题吗? 第一个问题,您是如何创建 RESTful 应用程序的?使用 Servlet、一些库等? 如果您尝试使用 IP 作为唯一标识符,如果您的一些用户来自 NAT 路由器后面,那么您将受到伤害。 【参考方案1】:

将HttpServletRequest 注入到您的 Rest Service 中:

import javax.servlet.http.HttpServletRequest;

@GET
@Path("/yourservice")
@Produces("text/xml")
public String activate(@Context HttpServletRequest requestContext,@Context SecurityContext context)

   String ipAddressRequestCameFrom = requestContext.getRemoteAddr();
   // header name is case insensitive
   String xForwardedForIP = req.getHeader("X-Forwarded-For");
   
   //Also if security is enabled
   Principal principal = context.getUserPrincipal();
   String userName = principal.getName();


正如@Hemant Nagpal 所提到的,如果负载平衡器将其插入请求中,您还可以检查X-Forwarded-For 标头以确定真正的来源。 根据这个answer,getHeader() 调用不区分大小写。

【讨论】:

requestContext.getRemoteAddr() 就足够了(没有toString() requestContext.getRemoteAddr() 会给你 apigateway 的 IP 地址,如果你正在使用它。相反,您可以使用如下代码:String remoteAddr = null; remoteAddr = request.getHeader("X-FORWARDED-FOR"); if (remoteAddr == null || "".equals(remoteAddr)) remoteAddr = request.getRemoteAddr(); else StringTokenizer tokenizer = new StringTokenizer(remoteAddr,","); while(tokenizer.hasMoreTokens()) remoteAddr = tokenizer.nextToken(); break; 【参考方案2】:

我认为你可以通过请求对象获取IP。

如果我没记错的话,request.getRemoteAddr() 左右。

【讨论】:

也许我遗漏了一些东西,但我没有请求对象。这是一个 JAX-RS Restful Web 服务。我确实可以访问 Request 上下文对象,但它没有 getRemoteAddr() 方法,并且似乎与“条件获取”有关……不管是什么。 嗯..你不能做类似@Context HttpServletRequest request 然后使用这个对象 request.getRemoteAddr() 吗?【参考方案3】:

你可以这样做:

@WebService
public class YourService 

   @Resource
   WebServiceContext webServiceContext; 

   @WebMethod 
   public String myMethod()  

      MessageContext messageContext = webServiceContext.getMessageContext();
      HttpServletRequest request = (HttpServletRequest) messageContext.get(MessageContext.SERVLET_REQUEST); 
      String callerIpAddress = request.getRemoteAddr();

      System.out.println("Caller IP = " + callerIpAddress); 

   

【讨论】:

【参考方案4】:

假设您正在使用 servlet 制作“Web 服务”,请求对象上相当简单的方法调用 .getRemoteAddr() 将为您提供调用者 IP 地址。

【讨论】:

不是 servlet,而是 Restful Web 服务(不同,对吗?)..而且我没有具有 getremoteAddr() 方法的对象。【参考方案5】:

如果您的应用程序在位于反向代理或负载平衡器后面的网络服务器上运行,则可以将该代理配置为在请求标头中注入请求的 IP 地址。不同的反向代理可以注入不同的标头。请查阅代理服务器的文档。我们在下面的示例中列出了几个最常用的,但这绝不是一个完整的列表。 当您的客户端使用(转发)代理时,它可能会插入标头来说明客户端 IP 地址是什么。或者它可能不会。此处插入的 IP 地址可能不正确。 这意味着您通过调用 request.getRemoteAddr() 获得的值是请求的直接上游源的 IP 地址。 正如我们所说,使用的不同代理有很多标头,但 x-forwareded-for 最有可能被代理插入。 最后一点,即使您从标头或 request.getRemoteAddr() 获得 IP 地址,也不能保证它是客户端 IP 地址。例如:如果您的代理不包含客户端的 IP 地址,那么您将获得代理或负载均衡器的 IP 地址。如果您的客户端在私有网络上工作并通过 NAT 网关连接到 Internet,则 HTTP 请求中的 IP 地址将是 NAT 服务器的地址。甚至对于黑客来说,注入具有不同 IP 地址的标头也很容易。因此,这意味着您无法可靠地找出发出请求的系统的 IP 地址。

 private static final String[] IP_HEADER_CANDIDATES =  
        "X-Forwarded-For",
        "Proxy-Client-IP",
        "WL-Proxy-Client-IP",
        "HTTP_X_FORWARDED_FOR",
        "HTTP_X_FORWARDED",
        "HTTP_X_CLUSTER_CLIENT_IP",
        "HTTP_CLIENT_IP",
        "HTTP_FORWARDED_FOR",
        "HTTP_FORWARDED",
        "HTTP_VIA",
        "REMOTE_ADDR" ;

    public static String getClientIpAddress(HttpServletRequest request) 
        for (String header : IP_HEADER_CANDIDATES) 
            String ip = request.getHeader(header);
            if (ip != null && ip.length() != 0 && !"unknown".equalsIgnoreCase(ip)) 
                return ip;
            
        
        return request.getRemoteAddr();
    

【讨论】:

以上是关于休息 - 如何获取调用者的 IP 地址的主要内容,如果未能解决你的问题,请参考以下文章

WebApi中,怎么获取接口调用者的外网ip地址

oracle如何获取调用者的IP,机器名等信息,以及他们操作的SQL

如何在 ruby​​ 中获取 IP 地址、引用者和用户代理?

如何使用inspect从Python中的被调用者那里获取调用者的信息?

如何在被调用的方法中获取调用者的方法名?

如何获取 SQL 调用者的 SPID