SoapClient 尝试获取架构文件时出现 401 身份验证错误 [英] 401 Authentication Error when SoapClient tries to fetch schema file

查看:60
本文介绍了SoapClient 尝试获取架构文件时出现 401 身份验证错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的应用程序经常连接到第三方服务器以通过 SOAP/WSDL 获取数据:

My application routinely connects to a third-party server to fetch data via 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 文件,现在当应用程序尝试连接时我收到以下两个错误:

Everything has been great for the last year, but they recently updated their WSDL file and now when the application tries to connect I'm getting the following two errors:

SoapClient::SoapClient(http://[the-domain]:80/[path]?xsd=1): 无法打开流:HTTP 请求失败!HTTP/1.1 401 未经授权

SoapClient::SoapClient():I/O 警告:无法加载外部实体http://[the-domain]:80/[path]?xsd=1">

当我查看 WSDL XML 文件时,似乎有问题的可卸载文件是它试图导入的文档模式文件 (schemaLocation):(来自 WSDL:)

When I look at the WSDL XML file, it appears that the offending unloadable file is the document schema file (schemaLocation) that it's trying to import: (from WSDL:)

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

我一直反对这个问题有一段时间了,据我所知,这个问题是两件事之一:

I've been beating my head against this for a while, and as far as I can tell, the issue is one of two things:

  1. 当我在浏览器中加载该架构 URL 时(在浏览器身份验证后),它 302 重定向 到一个 https url(并删除端口声明).尝试导入架构时,SOAP 调用是否可能不遵循重定向?
  2. 鉴于错误消息是 401 错误这一事实 - 尝试导入架构时 SOAP 调用是否可能未传递凭据?架构文件需要与 WSDL 文件相同的身份验证,但可能服务器在尝试导入时没有将身份验证扩展到架构?
  1. When I load that schema URL in a browser (after browser authentication) it 302 redirects to a https url (and drops the port declaration). Is it possible that SOAP call won't follow the redirect when trying to import the schema?
  2. Given the fact that the error message is a 401 error - is it possible that the SOAP call is not passing credentials when trying to import the schema? The schema file requires the same authentication as the WSDL file, but maybe the server is not extending the authentication to the schema when it tries to import?

假设这是第二个问题,有什么方法可以强制系统使用不同的模式 URL,而无需下载 WSDL 文件、编辑它并在本地存储/引用它?如果是这样,我可以尝试在 URL (http://username:password@domain....) 中传递凭据?

Assuming that it's the second issue, is there any way that I can force the system to use a different schema URL without downloading the WSDL file, editing it, and storing it/referencing it locally? If so I could try passing the credentials in the URL (http://username:password@domain....)?

如果我唯一的尝试是创建 WSDL 和 XSD 架构文件的修改副本,那就这样吧,但我很想知道是否有人有任何想法可以让我避免这种情况(因为架构确实发生了变化不时).

If my only shot is to create a modified copy of both the WSDL and XSD schema file, so be it, but I'd love to hear if anyone has any thoughts that would let me avoid this (as the schema does change from time-to-time).

推荐答案

看起来 PHP SoapClient 坚持 相同域策略(包括方案),用于在 WSDL 请求中发送基本身份验证用户名和密码,该请求是为了在 WDSL 模式中导入 xsd 文件而完成的.

It looks like the PHP SoapClient sticks to the same domain policy (including scheme) for sending the Basic Auth username and password in the WSDL request which is done to import the xsd file in the WDSL schema.

因此,如果 WSDL url 具有 https 方案并且导入具有 http 方案,则 PHP 不会发送基本身份验证信息,因为在请求 http 导入 url(这会损害身份验证信息的机密性).

So if the WSDL url has a https scheme and the import has a http scheme, PHP is not sending the basic authentication info since the connection is not encrypted anymore when requesting the http import url (which would compromise the confidentiality of the authentication info).

但是,似乎至少对于某些 PHP 版本(可能在较新版本中已修复),即使 http url 重定向到 https 网址,身份验证问题仍然存在(在同一个域上).在重定向到具有相同域的安全 URL 之后,PHP 当然可以再次包含给定的基本身份验证信息.

However it seems that at least for some PHP versions (might be fixed in newer versions) the authentication problem persists even if the http url redirects to the https one (on the same domain). After the redirect to a secure URL with the same domain PHP could off course include the given Basic Auth info again.

最后,我发现解决此问题的唯一巧妙方法是让对方更改其 WSDL 内容以导入安全 URL(https 一个),该 URL 具有与以下相同的方案、域和端口WDSL 网址本身.

In the end the only neat way I found to fix this was making the other party change their WSDL content to import a secure URL (https one) which has the same scheme, domain and port as the WDSL url itself.

如果这不是您的选择,您可以随时采取解决方法,即将 WSDL 以及导入保存为本地文件并参考 WDSL file而不是 URL.当然,这也意味着您必须更改 WSDL 以导入正确的本地文件(而不是 http URL),并且可能还有其他导入.不幸的是,在这种情况下,这是我所知道的唯一解决方法.

If that is not an option for you off course you could always go for the workaround which is to save the WSDL as well as the import(s) as local files and refer to the WDSL file instead of the URL. Off course this would also mean you would have to change the WSDL to import the right local file (instead of the http URL), and possibly other imports as well. Unfortunately this is the only workaround I know of in this case.

我还发现了这个 PHP 错误报告,这可能是相关.

I also found this PHP bug report which might be related.

这篇关于SoapClient 尝试获取架构文件时出现 401 身份验证错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆