【问题标题】:How do I get the PHP SOAP client to communicate with a service running over SSL with an invalid certificate如何让 PHP SOAP 客户端与通过 SSL 运行且证书无效的服务进行通信
【发布时间】:2012-09-11 15:37:44
【问题描述】:

我正在尝试使用 PHP SOAP 客户端使用 SOAP 服务,但它失败并显示以下消息:

SoapFault: SOAP-ERROR: Parsing WSDL: Couldn't load from 'https://domain.com/webservice.asmx?wsdl' : failed to load external entity "https://domain.com/webservice.asmx?wsdl"\n in /Users/andrewdchancox/Projects/test/testsoap.php on line 10

我已经下载了 wsdl 文件并从本地 apache 实例提供了它,它加载时没有任何问题。我唯一能想到的可能是 Web 服务正在使用自签名证书通过 SSL 运行 - 当我获取 wsdl 时,我收到以下错误:

--2012-09-11 16:28:39--
https://domain.com/webservice.asmx?wsdl
Resolving domain.com (domain.com)... 11.111.111.11
Connecting to domain.com (domain.com)|11.111.111.11|:443... connected.
ERROR: The certificate of ‘domain.com’ is not trusted.
ERROR: The certificate of ‘domain.com’ hasn't got a known issuer.

我搜索并彻底阅读了 PHP SOAP 客户端的 PHP 文档 - http://php.net/manual/en/class.soapclient.php 和它的构造函数 - http://www.php.net/manual/en/soapclient.soapclient.php,但没有找到任何帮助。

有人有什么想法吗?

【问题讨论】:

  • 这个问题很久以前就解决了 - 我今天一直在使用另一个 SOAP 服务,它在同一个开发环境中通过 SSL 运行,并且一切正常。
  • @AndrewHancox:你是如何解决你的问题的?我遇到了同样的问题。

标签: php soap ssl


【解决方案1】:

这是两年前的事了,但我认为值得回答。

PHP 中的 SoapClient 类使用 PHP 流通过 HTTP 进行通信。由于各种原因,基于 PHP 流的 SSL 不安全1,但在这种情况下,您的问题是它太安全了。

解决方案的第一步是在构建 SoapClient 时使用stream_context 选项2。这将允许您指定更高级的 SSL 设置3

// Taken from note 1 below.
$contextOptions = array(
    'ssl' => array(
        'verify_peer'   => true,
        'cafile'        => '/etc/ssl/certs/ca-certificates.crt',
        'verify_depth'  => 5,
        'CN_match'      => 'api.twitter.com',
        'disable_compression' => true,
        'SNI_enabled'         => true,
        'ciphers'             => 'ALL!EXPORT!EXPORT40!EXPORT56!aNULL!LOW!RC4'
    )
);
$sslContext = stream_context_create($contextOptions);
// Then use this context when creating your SoapClient.
$soap = new SoapClient('https://domain.com/webservice.asmx?wsdl', array('stream_context' => $sslContext));

您的问题的理想解决方案是创建您自己的 CA 证书,使用它来签署 SSL 证书,然后将您的 CA 证书添加到 cafile。更好的做法可能是cafile 中拥有该证书,以避免某些流氓 CA 为您的域签署其他人的证书,但这并不总是可行的。

如果您的操作不需要安全(例如在测试期间),您还可以在流上下文中使用 SSL 设置来降低连接的安全性。 allow_self_signed 选项将允许自签名证书:

$contextOptions = array(
    'ssl' => array(
        'allow_self_signed' => true,
    )
);
$sslContext = stream_context_create($contextOptions);
$soap = new SoapClient('https://domain.com/webservice.asmx?wsdl', array('stream_context' => $sslContext));

链接:

  1. Survive the Deep End: PHP Security - Transport Layer Security (HTTPS, SSL, and TLS) - PHP Streams
  2. PHP: SoapClient::SoapClient
  3. PHP: SSL Context Options

【讨论】:

  • 感谢您的回答,即使在 2 年后 - 这篇文章是唯一让我过去几天头疼的事情(特别是,在调用 SoapClient 构造函数之外创建流上下文,并指向cafile)
猜你喜欢
  • 2020-02-14
  • 1970-01-01
  • 2014-06-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-18
  • 2014-04-11
相关资源
最近更新 更多