我的应用程序通常连接到第三方服务器,以通过SOAP/WSDL获取数据:
$this->soap_client = new SoapClient("https://[the-domain]:443/[path]?wsdl", array(
'trace'=>1,
'login'=>$this->username,
'password'=>$this->password,
'exceptions' => true,
'cache_wsdl' => WSDL_CACHE_NONE
)
去年一切都很好,但是他们最近更新了WSDL文件,现在当应用程序尝试连接时,出现以下两个错误:
和
当我查看WSDL XML文件时,似乎有问题的可卸载文件是它尝试导入的文档架构文件(schemaLocation):(从WSDL :)
<types>
<xsd:schema>
<xsd:import namespace="[irrelevant]" schemaLocation="http://[the-domain]:80/[path]?xsd=1"/>
</xsd:schema>
</types>
我一直对此表示怀疑,据我所知,问题是两件事之一:
302 redirects
转换为https
URL(并删除端口声明)。尝试导入模式时,SOAP调用是否可能不遵循重定向? 假设这是第二个问题,是否有任何方法可以强制系统使用其他架构URL,而无需下载WSDL文件,对其进行编辑以及将其存储/本地引用呢?如果是这样,我可以尝试在URL(
http://username:password@domain....
)中传递凭据吗?如果我唯一的想法是创建WSDL和XSD模式文件的修改后的副本,就可以了,但是我很想听听是否有人有让我避免这种想法的想法(因为模式确实会随着时间而改变-时间)。
最佳答案
看起来PHP SoapClient坚持使用same domain policy(包括方案)在WSDL请求中发送基本身份验证用户名和密码,此操作是在WDSL模式中导入xsd文件的。
因此,如果WSDL URL具有https
方案,而导入具有http
方案,则PHP将不发送基本身份验证信息,因为在请求http
导入URL时连接不再加密(这将损害身份验证信息的 secret 性)。
但是,似乎至少对于某些PHP版本(在新版本中可能已修复),即使http
url重定向到https
一个(在同一域上),身份验证问题仍然存在。在重定向到具有相同域的安全URL后,PHP可能会偏离路线,再次包含给定的基本身份验证信息。
解决方案
最后,我发现解决此问题的唯一好方法是让另一方更改其WSDL内容,以导入一个安全的URL(https
一个),该URL具有与WDSL URL本身相同的方案,域和端口。
解决方法
如果这不是您的选择,那么您始终可以采用一种变通方法,即将WSDL和导入文件另存为本地文件,并引用WDSL文件而不是URL。当然,这也意味着您必须更改WSDL才能导入正确的本地文件(而不是http
URL),并且可能还需要导入其他文件。不幸的是,在这种情况下,这是我所知道的唯一解决方法。
PHP Bug?
我也发现了这个PHP bug report可能与之有关。