使用soapclient连接到https主机:如何解决SSL问题?

时间:2013-06-05 09:22:11

标签: php soap ssl https handshake

TLDR

我似乎无法使用SoapClient连接到https端点。当我的wget返回handshake failure时,我怀疑这是原因。

如何使用PHP向此服务器发送SOAP请求?

完整

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

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

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

场合

  • 我正在基于我在本地使用的wsdl创建一个PHP Soapclient
  • 如果我更改了端点,我会收到Request和Response标头,一切都按预期工作。
  • 可以从我的服务器访问该计算机,但是当我使用wget连接到它时会出现问题(见下文)     无法建立SSL连接。
  • 使用openssl连接(见下文)
  • 也可以看到问题

我尝试了什么。

有很多关于“没有连接!”的话题,但显然有很多“我的路由器很糟糕,我在地址等处输了一个错误”。我确实尝试了多次建议的这些设置,但更多的是作为“cut'n'paste”解决方案,以确保它不起作用“然后出于真正的推理。我的一些评论添加

为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;

(首先只有ssl选项verify_peerallow_self_signed。然后我添加了https数组,最后我将ciphers键添加到{ {1}}。)

我找到了对this bug的引用,但是1)我没有收到警告,2)它似乎与代理有关,3)我的版本不应再有bug了。我正在运行ssl

当我尝试忘记网址时,我得到:

php 5.3.10

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

    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

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

$ 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:

我试图在this question中添加curl-wrapper,并将ssl_version设置为3(因为这似乎适用于上面的$ 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. ** 命令)。那个包装器确实丢弃了一些参数,所以我不确定它会有多完整。此外,我仍然会收到握手错误,除非我明确将检查设置为false。如果我这样做(见下文),我会得到一个空洞的回应。

openssl

原因

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

额外测试。

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

所以在上面看来,我确实有一种方法可以将curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, 0); curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, false); 挤出服务器,但这并不成功。但这可能是第二个问题?不确定。

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

3 个答案:

答案 0 :(得分:1)

有趣。尝试添加:

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

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

答案 1 :(得分:1)

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

作为一种解决方法并且安全失败,我使用了一个捕获来获取肥皂信封请求(类似于您在上面测试过的):

$xml = $client->__getLastRequest()

并通过curl发送:


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

这让我至少可以前进了。

答案 2 :(得分:0)

您是否在php_openssl.dll启用了php.ini

参考:

PHP SOAP cannot connect to an SSL WSDL source