PHP SoapClient请求作为客户端IP而不是服务器IP接收

时间:2012-12-11 01:28:12

标签: php soap

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

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

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

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

我尝试发送一个简单的请求,除了IP地址之外还会遇到不同的错误,但我一直遇到IP地址问题。

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

4 个答案:

答案 0 :(得分:4)

好吧,我想出来了 - 至少对我自己的情况而言。您阅读的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地址。所以不要忘记!

答案 1 :(得分:3)

这是一个艰难的问题,因为这个问题并没有真正清楚地说明实际涉及哪些系统以及使用何种类型的IP白名单。

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

在WSDL中,包含真实SOAP服务器的URL。请注意,服务器本身可能与WSDL描述完全不同,但这种设置也不常见。您可以通过将选项数组传递到带有条目SoapClient的{​​{1}}来覆盖该位置。这不会改变WSDL资源的加载,但是对SOAP服务的所有请求都会转到不同的基本URL。

  

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

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

那么白名单在哪里?如果它在系统3上,则必须列出系统2使用的IP。请注意,每台联网计算机都有多个IP地址:至少是该网络设备中的一个,加上127.0.0.1。使用IPv6,每个设备甚至有多个地址。使用"location" => "http://different.domain.example/path/to/service"在这里确实没有意义 - 此外,传输方式上的系统(如透明代理)也可能影响IP。您不应将SERVER_ADDR用作白名单的条目。您应该检查shell上的网络设置,以了解使用的网络设备以及它具有的IP。或者询问您要联系的服务器,以检查他们看到的IP。

  

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

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

它没有正确描述经验丰富的“IP地址问题”。他们怎么看?它是“连接失败”的超时,还是任何正确的HTTP拒绝与某些4xx状态代码触发SoapFault?如果描述更好,这个问题才能真正解决。

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

答案 2 :(得分:1)

好的,所以我发现获取服务器IP而不是客户端IP是不可能的。非常不幸......

我猜您必须使用login / pass

跟踪凭证

答案 3 :(得分: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传递给webservice。你也可以通过在php-soap(这个例子中)检查调用者的ip(你的情况下服务器ip,这是唯一的)来保护你的页面。

快速又脏。

相关问题