6

我正在尝试在另一个域上运行 SOAP 方法,该方法必须从列入白名单的 IP 地址接收,但 WSDL 似乎以某种方式认为请求来自客户端而不是服务器。该调用从表单收集信息,使用 AJAX 发布到 PHP 函数,该函数将字段格式化为 API 友好格式,然后通过 PHP SoapClient 发送。

我认为最好的方法是调查使用 SoapClient 发送的标头,但标头没有列出任何 IP 地址(主机、连接、用户代理、内容类型、SOAPAction 和内容长度)。

首先,我阅读了 SOAP 端点的文档。它显然没有指定要传递的任何特定参数,这无论如何都是没有意义的,因为我只能伪造一个 IP 地址。然后,我阅读了PHP SoapClient的文档。有趣的是,我找不到设置 IP 地址的确切位置,但我确实找到了一条提到 using 的评论'stream_context',但也没有运气。

我还记录了每个请求,包括$_SERVER['SERVER_ADDR']$_SERVER['REMOTE_ADDR'],它们都按预期报告 IP 地址;他们的技术支持告诉我他们正在收到来自'REMOTE_ADDR'价值的请求。

我尝试发送一个简单的请求,预计会收到除 IP 地址之外的其他错误,但我不断收到 IP 地址问题。

有什么方法可以更确定我正在使用正确的(服务器)IP 发送 SOAP 请求?

4

4 回答 4

5

好吧,我想通了——至少就我自己的情况而言。您阅读的 PHP 手册中的注释是正确的(假设我们谈论的是同一个),但是,我还需要在我的 IP 地址中包含端口。所以我最终使用的代码是:

$options = array('socket' => array('bindto' => 'xxx.xxx.xx.xxx:0'));
$context = stream_context_create($options);
$client = new SoapClient($url, 
    array('trace' => 1, 'exception' => 0, 'stream_context' => $context));

看,以前,我没有包含“:0”,我只是包含了 IP 地址。所以不要忘记这一点!

于 2013-07-22T10:04:16.060 回答
3

这是一个棘手的问题,因为这个问题并没有真正清楚地描绘出实际涉及哪些系统以及在何处以及使用哪种 IP 白名单。

使用 SOAP 时,有关服务的主要信息源包含在 WSDL 资源中。它应该是通过HTTP请求获得的,如果主资源的XML有xi:include元素,它可能会触发额外的HTTP请求。所有这些请求都源自充当 SOAP 客户端的系统。您不能在此处选择要使用的 IP 地址(除非您有一个非常奇特的设置,即有两个接口都有到目标系统的有效路由,并且选择正确的 IP 是应用程序的任务 - 我不认为这个这里就是这种情况,我不再考虑它了——你需要为此配置一个流上下文,设置“bindto”选项,并将其传递给 SoapClient)。

在 WSDL 中,包含了真正的 SOAP 服务器的 URL。请注意,服务器本身可能位于与 WSDL 描述完全不同的域中,尽管这样的设置也不常见。您可以通过将选项数组传递给SoapClient带有条目的条目来覆盖该位置"location" => "http://different.domain.example/path/to/service"。这不会改变 WSDL 资源的加载,但是对 SOAP 服务的所有请求都会转到那个不同的基本 URL。

该调用从表单收集信息,使用 AJAX 发布到 PHP 函数,该函数将字段格式化为 API 友好格式,然后通过 PHP SoapClient 发送。

这里提到了很多客户端和服务器。提到了 AJAX,这让我相信涉及到浏览器。这是系统 1,充当客户端。一个请求被发送到一些 PHP。这个目标是系统 2,在这里充当服务器。它对其进行转换,并充当客户端,将 SOAP 请求发送到充当另一台服务器的系统 3。

那么白名单在哪里呢?如果它在系统 3 上,它必须列出系统 2 使用的 IP。请注意,每台联网计算机都有多个 IP 地址:至少来自该网络设备的 IP 地址加上 127.0.0.1。使用 IPv6,每台设备甚至有多个地址。在这里使用$_SERVER['SERVER_ADDR']并没有真正的意义 - 此外,传输方式的系统,如透明代理,也可能影响 IP。您不应使用 SERVER_ADDR 作为白名单的条目。您应该真正检查 shell 上的网络设置,以了解使用了哪个网络设备,以及它具有什么 IP。或者询问您要联系的服务器以检查他们看到的 IP。

我还记录了每个请求,包括$_SERVER['SERVER_ADDR']$_SERVER['REMOTE_ADDR'],它们都按预期报告 IP 地址;他们的技术支持告诉我他们正在接收来自“REMOTE_ADDR”值的请求。

这是奇怪的事情。系统 2 上的 SERVER_ADDR 和 REMOTE_ADDR 已按预期设置。我将其读为 REMOTE_ADDR 是系统 1 的 IP,而 SERVER_ADDR 是系统 2 的 IP。但是系统 3 看到系统 1 的 IP?这里发生了什么?我真的很想从原始海报中获得更多反馈,但这个问题已经有半年了。

并且它没有对所经历的“IP地址问题”进行适当的描述。他们是怎么看的?是“连接失败”的超时,还是任何适当的 HTTP 拒绝以及触发 SoapFault 的某些 4xx 状态代码?只有描述得更好,才能真正解决这个问题。

然而,我确实怀疑可能涉及复杂的代码,而真正的 SOAP 请求实际上是由浏览器/系统 1 发送的,因为系统 2 上生成的 XML 被镜像回系统 1,然后发送到系统 3。它至少可以解释为什么在系统 3 上可以看到系统 1 的 IP。

于 2013-07-25T20:36:04.537 回答
1

有同样的问题。你有两个解决方案。两者都需要额外的步骤来调用 Web 服务。

1) 使用file_get_contents访问通过 php soap 实际询问 WS 的页面。例子:

public function test() {            
    $result = file_get_contents('http://your.domain.com/pages/php-soap?params=your-params');
    header("Content-type: text/xml; charset=utf-8");
    echo $homepage;         
}

2) 将CURL用于相同目的。

这样,您将服务器 ip 传递给 web 服务。您还可以通过检查 php-soap(此示例)调用者的 ip(在您的情况下为服务器 ip,这是唯一的)来保护您的页面。

又快又脏。

于 2013-04-08T07:43:01.947 回答
1

好的,所以我发现无法获取服务器IP而不是客户端IP。很不幸...

我想您将不得不使用登录/通行证来跟踪凭据

于 2012-12-11T02:20:07.747 回答