当SoapClient尝试获取模式文件时发生401身份验证错误

我的应用程序通常连接到第三方服务器以通过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 :)

<types>
<xsd:schema>
<xsd:import namespace="[irrelevant]" schemaLocation="http://[the-domain]:80/[path]?xsd=1"/>
</xsd:schema>
</types>

一段时间以来,我一直在殴打我的头,据我所知,这个问题是两件事之一:

  • 当我在浏览器中加载模式URL时(浏览器认证之后),它将302 redirectshttps url(并丢弃端口声明)。 尝试导入模式时,SOAP调用是否可能不会遵循重定向?
  • 鉴于错误消息是401错误 - 尝试导入架构时SOAP调用是否可能未传递凭据? 模式文件需要与WSDL文件相同的身份验证,但服务器在尝试导入时可能不会将身份验证扩展到模式?
  • 假设这是第二个问题,是否有任何方法可以强制系统使用不同的模式URL,而无需下载WSDL文件,进行编辑,并将其存储在本地/引用它? 如果是这样,我可以尝试在URL( http://username:password@domain.... )中传递凭据?

    如果我唯一的想法是创建一个WSDL和XSD模式文件的修改副本,那就这么做吧,但是我很想听听有没有人能够让我避免这种想法(因为架构确实从时间 - 到时间)。


    它看起来像PHP SoapClient坚持相同的域策略(包括方案),用于在WSDL请求中发送Basic Auth用户名和密码,以完成导入WDSL模式中的xsd文件。

    因此,如果WSDL url具有https方案并且导入具有http方案,则PHP不会发送基本认证信息,因为在请求http导入url时(这会危及认证信息的机密性),连接不再被加密。

    然而,至少对于某些PHP版本(可能会在较新版本中修复),即使http url重定向到https (在同一个域中),身份验证问题仍然存在。 重定向到具有相同域PHP的安全URL后,可能会再次包含给定的基本身份验证信息。

    最后,我发现解决这个问题的唯一方法就是让另一方更改他们的WSDL内容来导入一个与WDSL url本身具有相同方案,域和端口的安全URL( https )。

    解决方法

    如果这不是您的选择,那么您总是可以选择将WSDL以及导入保存为本地文件的解决方法,并引用WDSL文件而不是URL。 当然,这也意味着你将不得不改变WSDL来导入正确的本地文件(而不是http URL),也可能导入其他导入。 不幸的是,这是我所知道的唯一解决方法。


    PHP的错误?

    我也发现这个PHP错误报告可能是相关的。


    我会给cURL一个尝试,它有一个选项用于跟随重定向

    如何从PHP发布SOAP请求

    链接地址: http://www.djcxy.com/p/20211.html

    上一篇: 401 Authentication Error when SoapClient tries to fetch schema file

    下一篇: Copy RDLC report text and paste in notepad