12

TLDR

我似乎无法使用SoapClient. 当我的 wget 返回 ahandshake failure时,我怀疑这是原因。

如何使用 SOAP 向该服务器发出 SOAP 请求PHP

完全的

我正在尝试连接到 SOAP 服务器 (https)。它没有客户端证书身份验证,因此连接应该非常简单,但遗憾的是它不是。

问题是我不断收到Could not connect to host消息。

我正在使用的连接方法适用于另一台服务器,并且我已验证我正在正确设置该服务器的位置(将其更改为我控制的服务器,并且我在那里得到响应)。我怀疑问题出在与服务器的 https/ssl 连接上。

情况

  • 我正在Soapclient基于我在本地拥有的 wsdl 创建一个 PHP。
  • 如果我更改端点,我会得到请求和响应标头,并且一切都按预期工作。
  • 这台机器可以从我的服务器访问,尽管当我wget用来连接它时出现一个问题(见下文)无法建立 SSL 连接。
  • 这个问题在 openssl 连接中也很明显(见下文)

我试过了。

有很多关于“没有连接!”的话题,但显然有很多“我的路由器坏了,我的地址打错了等等”。我确实尝试了多次建议的这些设置,但更多的是作为“剪切粘贴”解决方案,以确保它不起作用”然后出于真正的推理。我添加了一些评论

为 wsdl 选项创建一个stream_context。我努力了

$context = stream_context_create(
              array(
                'ssl' => array(
                           'verify_peer' => false,  //default
                           'allow_self_signed' => true, //needs verify peer, tried that
                           'ciphers'=>"SHA1", // quite random.
                   ),
                'https' => array(
                           'curl_verify_ssl_peer'  => false,
                           'curl_verify_ssl_host'  => false
                          )
      )
            );
$options['stream_context'] = $context;

(首先只有带有and的ssl选项。然后我添加了数组,最后我添加了键。)verify_peerallow_self_signedhttpsciphersssl

我找到了对这个 bug的引用,但是 1)我没有收到那个警告,2)它似乎与代理相关,3)我的版本应该不再有这个 bug。我在跑php 5.3.10

当我尝试获取网址时,我得到:

    wget https://[[servername]]/SOAP
    Resolving [[servername]] ([[servername]])... xxx.xxx.xxx.xxx
    Connecting to [[servername]]([[servername]])|xxx.xxx.xxx.xxx|:443... connected.
    OpenSSL: error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure

如果我尝试连接 openssl,我会得到:

$ openssl s_client -connect [[server]]:443 -state
CONNECTED(00000003)
SSL_connect:before/connect initialization
SSL_connect:unknown state
SSL3 alert read:fatal:handshake failure
SSL_connect:error in unknown state
3074463944:error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure:s23_clnt.c:724:

但是如果我强制使用 ssl3,我会得到预期的结果

$ openssl s_client -ssl3 -connect [[server]]:443 -state
CONNECTED(00000003)
SSL_connect:before/connect initialization
SSL_connect:SSLv3 write client hello A
SSL_connect:SSLv3 read server hello A
**happy certificate stuff. this is good**
Protocol  : SSLv3
Cipher    : DHE-RSA-AES256-SHA
**more happy certificate stuff. **

我试图从这个问题中添加 curl-wrapper,并将 ssl_version 设置为 3(因为这似乎适用于openssl上面的命令)。该包装器确实丢弃了一些参数,所以我不确定这将是多么完整。此外,除非我明确地将检查设置为 false,否则我仍然会收到握手错误。如果我这样做(见下文),我会得到一个空的响应。

curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, false);

原因

如上所述,我怀疑 ssl 握手,但我不知道如何修复它。我不怀疑 wsdl 或客户端创建存在问题,因为连接确实与另一个 wsdl、具有不同位置集的相同 wsdl 等一起工作。纯粹是这个(https)端点让我头疼。

额外的测试。

正如上面使用卷曲包装器的测试一样,我尝试发送一个最小的肥皂信封,正如@halfwarr 似乎在评论中建议的那样。Als 返回一个空响应。

因此,在上面看来,我确实有一种方法可以http 204从服务器中挤出一个,但这几乎没有成功。但这可能是第二个问题?没有把握。

我假设我需要尝试强制使用 ssl3,但我不知道如何(这也可能是错误的路径,所以我试图在这里没有XY 问题:)

4

3 回答 3

1

最新版本 PHP 5.5.3 将允许您设置 SSL 版本。我见过其他能够使用 stream_context 的人,但是我也无法完成这项工作。

作为一种变通方法和故障保险,我使用了一个捕获来获取肥皂信封请求(类似于您上面测试的内容):

$xml = $client->__getLastRequest()

并通过 curl 发送:


curl_setopt($ch, CURLOPT_SSLVERSION, 3);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

这让我至少可以向前迈进。

于 2013-09-10T00:30:32.440 回答
1

有趣的。尝试添加这个:

wget https://[[SERVER]]/soap/ —post-file=request.xml —header=”Content-Type: text/xml” -O response.xml

这会将结果保存为名为 response.xml 的文件。

于 2013-06-05T09:37:30.440 回答
0

php_openssl.dll在你的启用了php.ini吗?

参考:

PHP SOAP 无法连接到 SSL WSDL 源

于 2013-06-06T18:06:03.250 回答