Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/249.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 401 SoapClient尝试获取架构文件时发生身份验证错误_Php_Soap_Xsd_Soap Client - Fatal编程技术网

Php 401 SoapClient尝试获取架构文件时发生身份验证错误

Php 401 SoapClient尝试获取架构文件时发生身份验证错误,php,soap,xsd,soap-client,Php,Soap,Xsd,Soap Client,我的应用程序通常连接到第三方服务器,通过SOAP/WSDL获取数据: $this->soap_client = new SoapClient("https://[the-domain]:443/[path]?wsdl", array( 'trace'=>1, 'login'=>$this->username, 'password'=>$this->password, 'exceptions' => true, 'c

我的应用程序通常连接到第三方服务器,通过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://[域]:80/[路径]?xsd=1):无法打开流:http请求失败!HTTP/1.1 401未经授权

SoapClient::SoapClient():I/O警告:无法加载外部实体“http://[域]:80/[路径]?xsd=1”

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


我已经为此绞尽脑汁一段时间了,据我所知,这个问题是两件事之一:

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


    如果我唯一的办法是创建WSDL和XSD模式文件的修改副本,那就这样吧,但我很想听听是否有人有什么想法可以让我避免这种情况(因为模式确实会不时发生变化)。

    我想尝试一下cURL,它有一个选项来执行重定向


    看起来PHP SoapClient坚持在WSDL请求中发送基本身份验证用户名和密码(包括方案),这是为了在WDSL模式中导入xsd文件

    因此,如果WSDL url有一个
    https
    方案,而导入有一个
    http
    方案,那么PHP不会发送基本的身份验证信息,因为在请求
    http
    导入url时,连接不再加密(这会损害身份验证信息的机密性)

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

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

    变通办法 如果这不是您的一个选项,那么您可以随时进行变通,将WSDL和导入保存为本地文件,并引用WDSL文件而不是URL。当然,这也意味着您必须更改WSDL以导入正确的本地文件(而不是
    http
    URL),还可能需要其他导入。不幸的是,在这种情况下,这是我所知道的唯一的解决办法


    PHP错误?
    我还发现了可能与此相关的问题。

    您是否已经找到了解决方法?我正在努力解决这个问题。@tomvo-我最终只是创建了WSDL文件和模式文件的本地副本。我修改了本地WSDL文件以使用本地模式文件,然后
    SoapClient([localwsdl…]
    。这是可行的,但显然并不理想,因为如果架构被更新,系统将不会自动更新。我恐怕找不到比这更好的解决方法。因此,我昨天花了很多时间研究这个问题,我注意到,当我将用户名和密码作为参数传入时,它也会记住架构请求的基本身份。请参阅此snippet:是的,在我的情况下,我试过(实际上是在我问题的代码中设置的),我也试过在URL中传递它()但是没有一个成功。很高兴你能让它工作起来。我怀疑你的观点是正确的——错误报告的链接是我发现的一个非常好的概要。最终我改用了本地托管的版本,但我会检查它是否在更新的PHP版本上工作(我测试这个时使用的是5.4版本)
    <types>
    <xsd:schema>
    <xsd:import namespace="[irrelevant]" schemaLocation="http://[the-domain]:80/[path]?xsd=1"/>
    </xsd:schema>
    </types>