我的应用程序通常连接到第三方服务器以通过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文件,现在当应用程序尝试连接我收到以下两个错误时:
SoapClient::SoapClient(http://[the-domain]:80/[path]?xsd=1): failed to open stream: HTTP request failed! HTTP/1.1 401 Unauthorized
和
SoapClient::SoapClient(): I/O warning : failed to load external entity "http://[the-domain]:80/[path]?xsd=1"
当我查看WSDL XML文件时,看起来违规的可卸载文件是它尝试导入的文档模式文件(schemaLocation):(来自WSDL :) < / p>
<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架构文件的修改副本,那么就这样吧,但是我很想知道是否有人有任何想法会让我避免这种情况(作为架构)确实会不时变化。
答案 0 :(得分:3)
看起来PHP SoapClient坚持使用same domain policy(包括方案)在WSDL请求中发送Basic Auth用户名和密码,这是为了在WDSL模式中导入xsd文件。
因此,如果WSDL URL具有https
方案且导入具有http
方案,则PHP不会发送基本身份验证信息,因为在请求{{1}时连接不再加密} import url(会损害身份验证信息的机密性)。
然而,似乎至少对于某些PHP版本(可能在较新版本中修复),即使http
url重定向到http
(在同一域上),身份验证问题仍然存在。 在重定向到具有相同域的安全URL之后,PHP当然可以再次包含给定的基本身份验证信息。
最后,我找到解决此问题的唯一方法就是让另一方更改其WSDL内容以导入安全URL(https
one),该URL具有与WDSL url相同的方案,域和端口本身。
如果这不是您的选择,您可以随时寻找解决方法,即将WSDL以及导入保存为本地文件,并参考WDSL 文件而不是 URL 。当然,这也意味着您必须更改WSDL以导入正确的本地文件(而不是https
URL),以及可能还有其他导入。不幸的是,这是我在这种情况下唯一知道的解决方法。
我还发现了这可能与此相关的PHP bug report。
答案 1 :(得分:0)
我试试cURL,它有一个跟踪重定向的选项