简体   繁体   English

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

[英]PHP SoapClient request being received as client IP as opposed to server IP

I'm trying to run a SOAP method on another domain which must be received from a whitelisted IP Address, but the WSDL seems to somehow think the request is coming from the client and not the server. 我正在尝试在另一个域上运行SOAP方法,该方法必须从列入白名单的IP地址接收,但WSDL似乎以某种方式认为请求来自客户端而不是服务器。 The call collects information from a form, uses AJAX to post to a PHP function, which formats the fields into the API-friendly format, which is then sent via PHP SoapClient. 该调用从表单中收集信息,使用AJAX发布到PHP函数,该函数将字段格式化为API友好格式,然后通过PHP SoapClient发送。

I thought the best way to do this was to investigate the headers being sent with the SoapClient, but the headers don't list any IP address (Host, Connection, User-Agent, Content-Type, SOAPAction, and Content-Length). 我认为最好的方法是调查使用SoapClient发送的标头,但标头不会列出任何IP地址(主机,连接,用户代理,内容类型,SOAPAction和内容长度)。

First, I read the documentation of the SOAP endpoint. 首先,我阅读了SOAP端点的文档。 It doesn't apparently specify any specific parameter to be passed, which wouldn't make sense anyway because I'd just be able to fake an IP address. 它没有明确指定要传递的任何特定参数,这无论如何都没有意义,因为我只能伪造一个IP地址。 Then, I read the documentation for PHP SoapClient . 然后,我阅读了PHP SoapClient的文档。 Interestingly I couldn't find quite where the IP addresses were set, but I did find a comment which mentions using 'stream_context' , but had no luck with that either. 有趣的是,我找不到IP地址设置的位置,但我确实找到了一个注释,提到使用'stream_context' ,但也没有运气。

I am also logging every request, including $_SERVER['SERVER_ADDR'] and $_SERVER['REMOTE_ADDR'] , which are both reporting IP addresses as expected; 我还记录了每个请求,包括$_SERVER['SERVER_ADDR']$_SERVER['REMOTE_ADDR'] ,它们都按预期报告IP地址; technical support on their end tell me that they are receiving requests from the 'REMOTE_ADDR' value. 他们的技术支持告诉我他们正在接收来自'REMOTE_ADDR'值的请求。

I tried sending a bare-bones request and expected to get a different error besides the IP address, but I keep getting IP address problems. 我尝试发送一个简单的请求,并期望除IP地址之外得到一个不同的错误,但我不断收到IP地址问题。

Is there any way I can be more sure that I am sending the SOAP request with the proper (server) IP? 有什么方法可以让我更确定我是否使用适当的(服务器)IP发送SOAP请求?

Okay, I figured it out - at least for my own situation. 好吧,我想通了 - 至少对我自己的情况而言。 The comment in the PHP manual that you read was correct (assuming we're talking about the same one), however, I needed to include the port on my IP address as well. 您阅读的PHP手册中的注释是正确的(假设我们正在讨论相同的注释),但是,我还需要将端口包含在我的IP地址中。 So the code that I ended up using was: 所以我最终使用的代码是:

$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));

See, before, I had no included ":0" I had merely included the IP address. 看,之前,我没有包含“:0”我只包含了IP地址。 So don't forget that! 所以不要忘记!

This is a tough one, because the question does not really draw a clear picture on what systems are actually involved and where and what kind of IP whitelisting is in use. 这是一个艰难的问题,因为这个问题并没有真正清楚地说明实际涉及哪些系统以及使用何种类型的IP白名单。

When using SOAP, the primary source of information about the service is included in the WSDL resource. 使用SOAP时,有关服务的主要信息源包含在WSDL资源中。 It is supposed to be obtained via a HTTP request, and it might trigger additional HTTP request if the XML of the primary resource has xi:include elements. 它应该通过HTTP请求获得,如果主资源的XML具有xi:include元素,它可能会触发其他HTTP请求。 All these requests originate from the system that acts as the SOAP client. 所有这些请求都源自充当SOAP客户端的系统。 You cannot choose which IP address to use here (unless you have a very exotic setup of having TWO interfaces that BOTH have a valid route to the target system, and choosing the right IP is the task of the application - I wouldn't think this is the case here, and I stop thinking about it - you'd need to configure a stream context for this, set the "bindto" option, and pass it into the SoapClient). 你不能选择在这里使用哪个IP地址(除非你有一个非常奇特的设置,有两个接口,两个都有一个到目标系统的有效路由,选择正确的IP是应用程序的任务 - 我不认为这就是这里的情况,我不再考虑它 - 你需要为此配置一个流上下文 ,设置“bindto”选项,并将其传递给SoapClient)。

Inside the WSDL, the URL of the real SOAP server is contained. 在WSDL中,包含真实SOAP服务器的URL。 Note that the server itself might be on a completely different domain than the WSDL description, although such a setup would also be unusual. 请注意,服务器本身可能与WSDL描述完全不同,但这种设置也不常见。 You can override that location by passing an option array to the SoapClient with an entry "location" => "http://different.domain.example/path/to/service" . 您可以通过将选项数组传递给SoapClient并使用条目"location" => "http://different.domain.example/path/to/service"来覆盖该位置。 This would not change the loading of WSDL ressources, but all requests for the SOAP service would go to that different base URL. 这不会改变WSDL资源的加载,但是对SOAP服务的所有请求都将转到不同的基本URL。

The call collects information from a form, uses AJAX to post to a PHP function, which formats the fields into the API-friendly format, which is then sent via PHP SoapClient. 该调用从表单中收集信息,使用AJAX发布到PHP函数,该函数将字段格式化为API友好格式,然后通过PHP SoapClient发送。

There are plenty of clients and servers mentioned here. 这里提到了很多客户端和服务器。 AJAX is mentioned, which makes me believe a browser is involved. 提到了AJAX,这让我相信浏览器的参与。 This is system 1, acting as a client. 这是系统1,充当客户端。 A request gets sent to some PHP. 请求被发送到某些PHP。 This target is system 2, acting as a server here. 该目标是系统2,在此充当服务器。 It transforms it and, acting as a client, sends the SOAP request to system 3, which is acting as another server. 它转换它,并充当客户端,将SOAP请求发送到系统3,系统3充当另一个服务器。

So where is the whitelist? 那么白名单在哪里? If it is on system 3, it must list the IP that is used by system 2. Note that every networked computer has more than one IP address: At least the one from that network device, plus 127.0.0.1. 如果它在系统3上,则必须列出系统2使用的IP。请注意,每台联网计算机都有多个IP地址:至少是该网络设备中的一个,加上127.0.0.1。 With IPv6, there are even multiple addresses per each device. 使用IPv6,每个设备甚至有多个地址。 Using $_SERVER['SERVER_ADDR'] does not really make sense here - and additionally, systems that are on the transport way, like transparent proxies, might also influence the IP. 使用$_SERVER['SERVER_ADDR']在这里没有意义 - 此外,传输方式上的系统,如透明代理,也可能影响IP。 You shouldn't use the SERVER_ADDR as the entry for the whitelist. 您不应将SERVER_ADDR用作白名单的条目。 You should really check the network setup on a shell to know which network device is used, and what IP it has. 您应该检查shell上的网络设置,以了解使用的网络设备以及它具有的IP。 Or ask the server you are about to contact to check which IP they are seeing. 或者询问您要联系的服务器,以检查他们看到的IP。

I am also logging every request, including $_SERVER['SERVER_ADDR'] and $_SERVER['REMOTE_ADDR'] , which are both reporting IP addresses as expected; 我还记录了每个请求,包括$_SERVER['SERVER_ADDR']$_SERVER['REMOTE_ADDR'] ,它们都按预期报告IP地址; technical support on their end tell me that they are receiving requests from the 'REMOTE_ADDR' value. 他们的技术支持告诉我他们正在接收来自'REMOTE_ADDR'值的请求。

This is the strange thing. 这是奇怪的事情。 SERVER_ADDR and REMOTE_ADDR on system 2 are set as expected. 系统2上的SERVER_ADDR和REMOTE_ADDR按预期设置。 I read this as REMOTE_ADDR being the IP of system 1, and SERVER_ADDR being that of system 2. But system 3 sees the IP from system 1? 我读到这个,因为REMOTE_ADDR是系统1的IP,而SERVER_ADDR是系统2的IP。但系统3是否从系统1看到了IP? What is happening here? 这里发生了什么? I'd really like to have more feedback on this from the original poster, but the question is already half a year old. 我真的希望从原始海报中得到更多关于此的反馈,但这个问题已经有半年了。

And it does not have a proper description of the experienced "IP address problems". 它没有正确描述经验丰富的“IP地址问题”。 How are they seen? 他们怎么看? Is it a timeout with "connection failed", or is it any proper HTTP rejection with some 4xx status code that triggers a SoapFault? 它是“连接失败”的超时,还是任何正确的HTTP拒绝与某些4xx状态代码触发SoapFault? This problem can only really be solved if the description would be better. 只有描述更好才能真正解决这个问题。

I do suspect however, that there might be complicated code involved, and the real SOAP request is in fact sent by the browser/system 1, because the generated XML on system 2 is mirrored back to system 1 and then sent to system 3. It would at least explain why the IP of system 1 is seen on system 3. 然而,我确实怀疑可能涉及复杂的代码,并且实际的SOAP请求实际上是由浏览器/系统1发送的,因为系统2上生成的XML被镜像回系统1然后被发送到系统3。至少可以解释为什么在系统3上看到系统1的IP。

Ok, so I found out that it is impossible to get the server IP rather than the client IP. 好的,所以我发现获取服务器IP而不是客户端IP是不可能的。 Very unfortunate... 非常不幸......

I guess you will have to keep track of credentials by use of login/pass 我想你必须使用login / pass跟踪凭据

Had the same problem. 有同样的问题。 You have two solutions. 你有两个解决方案。 Both require an extra step for calling the web service. 两者都需要一个额外的步骤来调用Web服务。

1) Use file_get_contents to acces your page that actually interrogates the WS via php soap. 1)使用file_get_contents访问实际通过php soap询问WS的页面。 Example: 例:

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) Use CURL for the same purpose. 2)使用CURL用于相同目的。

That way, you'll pass the server ip to the webservice. 这样,您就可以将服务器ip传递给webservice。 You can also secure your pages, by checking in php-soap (this example) the ip of the caller (the server ip in your case, which is unique). 您还可以通过检查php-soap(此示例)调用者的IP(在您的情况下为服务器IP,这是唯一的)来保护您的页面。

Quick and dirty. 又脏又脏。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM