3

我正在使用 Apache HttpClient 生成 Post 请求并提交数据。由于远程应用程序依赖于提交数据的用户的 IP 地址,因此我想发送用户指定 IP 地址的发布请求。

我该如何配置?

public static void loginUser(String username, String password, String ip) throws Exception{
      try {
            HttpClient client = new DefaultHttpClient();
            HttpPost httppost = new HttpPost("http://login.myapp.com/");

            // Request parameters and other properties.
            List<NameValuePair> params = new ArrayList<NameValuePair>(2);
            params.add(new BasicNameValuePair("username",username));
            params.add(new BasicNameValuePair("password", password));
            httppost.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));

            // Execute and get the response.
            HttpResponse response = client.execute(httppost);
            HttpEntity entity = response.getEntity();

            if (entity != null) {
                //etc....
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

编辑:为避免混淆,

我想在 httprequest 标头中包含自定义 IP 地址,以便最终应用程序知道,此请求 [来自我的应用程序] 来自自定义 IP 地址,而不是来自运行我的应用程序的 IP 地址

假设我的应用程序在 IP 地址为“1.1.1.0”的服务器上运行。现在我的用户正在使用“test”、“test”、“199.199.199.0”执行 loginUser 方法。现在从应用程序到目标 URL 的 HTTP 请求应该是从“199.199.199.0”发送的

4

3 回答 3

8

OP写道:

我想在 httprequest 标头中包含自定义 IP 地址,以便最终应用程序知道此请求 [来自我的应用程序] 来自自定义 IP 地址,而不是来自运行我的应用程序的 IP 地址
......
假设我打开了 google.co .in,现在谷歌服务器知道这个请求来自我的 IP 地址。现在,如果我在 apache 中使用 HttpClient,我如何配置该 IP 地址,以便在谷歌服务器读取时,它将处理该请求最初来自该 IP 地址

你不能。

(这实际上是我在下面的原始答案中写的第 4 种解释。)

发件人的 IP 地址不作为 HTTP 标头发送。它在 IP 协议标头中的一个字段中发送。服务器在套接字级别获取发送者的 IP 地址,它不是从 HTTP 信息中获取的。

不,即使您愿意,也不能伪造您的 IP(这称为“欺骗”)。Java 没有对原始套接字的本机支持,您不能在 IP 级别修改信息。即使您可以(或者您使用 JNI 或一些出站数据包过滤应用程序或硬件),TCP 的性质也使 IP 欺骗对您的情况毫无用处(响应将被发送到假 IP,以及许多其他远远超出的困难这个答案的范围)。

所以,不,你不能做你想做的事。您需要让您尝试连接的服务器的管理员为您制定特殊规则,或者您需要认真重新考虑应用程序的设计。

编辑:其他选择

我在对该问题的评论中提到了这些,但为了完整起见,我也将它们包括在我的答案中:

根据您的安全要求,一种可能的解决方案是为您的用户设置 VPN 访问,这样用户必须先建立 VPN 连接,然后在内部服务器上运行您的 Web 应用程序。

您还可以通过 VPN 将您的 Web 服务器连接到您的网络,并通过 VPN 链接直接访问您的内部登录服务,而 Web 应用程序在 WAN 链接上运行。


这是我在 OP 澄清要求之前的原始答案:

不太清楚你在问什么,所以我会回答我能想到的可能性。

如果您的意思是让用户指定您发送帖子的服务器的 IP 地址,只需从 IP 地址构建 URL:

HttpPost httppost = new HttpPost("http://" + ip + "/");

如果您的意思是您希望服务器根据用户的IP地址做某事:当服务器收到请求时,用户的IP地址将在服务器端可用,您无需显式发送。究竟如何在服务器端访问该信息取决于您使用的服务器。

如果您的意思是希望用户能够指定发送到服务器的 IP 地址,只需像发送其他参数一样发送它:

params.add(new BasicNameValuePair("whatever", ip));

如果您的意思是您正在代表远程用户从您的服务器登录到依赖于用户 IP 地址的系统,并且您想假装是该远程用户以便登录成功:您不能。您尝试登录的系统具有适当的安全措施,以防止您尝试执行的操作。也许该系统的所有者可以为您的服务器的 IP 地址设置一个例外;你得问他们。

于 2013-08-16T05:15:07.837 回答
2

由于 TCP 的工作原理,这根本不可能。这是关于网络的。您使用什么工具/编程语言并不重要。
通过尝试将自己伪装成另一个 IP,TCP 无法完成握手,也无法发送您的数据。使用 UDP,您可以做到这一点,但 HTTP(Web)协议是基于 TCP 的,所以没有用处。

进一步阅读的一些参考资料:
TCP 握手
TCP 细节
UDP 细节

于 2013-08-16T07:06:23.450 回答
0

如果您有一个多宿主主机,即具有多个 IP 的主机,您可以选择使用哪个 IP 作为源 IP RequestConfig.setLocalAddress

对于特定请求:

HttpClient httpClient = HttpClientBuilder.create().build();

HttpGet request = new HttpGet("https://www.cloudflare.com/cdn-cgi/trace");
RequestConfig config = RequestConfig.custom().setLocalAddress(localAddr).build();
request.setConfig(config);

httpClient.execute(request).getEntity().writeTo(System.out);

或者对于整个HttpClient

RequestConfig config = RequestConfig.custom().setLocalAddress(localAddr).build();
HttpClient httpClient = HttpClientBuilder.create().setDefaultRequestConfig(config).build();

HttpGet request = new HttpGet("https://www.cloudflare.com/cdn-cgi/trace");
httpClient.execute(request).getEntity().writeTo(System.out);
于 2020-02-02T11:51:23.850 回答