php 使用soapclient 连接到https 主机:如何解决SSL 问题?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16936142/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Connecting to https host with soapclient: how to fix SSL problems?
提问by Nanne
TLDR
TLDR
I can't seem to connect to a https endpoint with a SoapClient
. As my wget returns a handshake failure
, I suspect that is the cause.
我似乎无法使用SoapClient
. 当我的 wget 返回 a 时handshake failure
,我怀疑这就是原因。
How can I do a SOAP request to this server with PHP
?
如何使用 向该服务器发出 SOAP 请求PHP
?
complete
完全的
I'm trying to connect to a SOAP server (https). It doesn't have client certificate authentication, so the connection should be pretty straightforward, but sadly it isn't.
我正在尝试连接到 SOAP 服务器 (https)。它没有客户端证书身份验证,因此连接应该非常简单,但遗憾的是它不是。
The problem is that I keep getting Could not connect to host
messages.
问题是我不断收到Could not connect to host
消息。
The connection method I'm using is working for another server and I've verified that I'm setting the location for this server correctly (changed it to a server I control, and I'm getting response there). I suspect the problem is with the https/ssl connection to the server.
我正在使用的连接方法适用于另一台服务器,并且我已经验证我正在正确设置该服务器的位置(将其更改为我控制的服务器,并且我在那里收到响应)。我怀疑问题出在与服务器的 https/ssl 连接上。
Situation
情况
- I'm creating a PHP
Soapclient
based on a wsdl I have locally. - If I change the endpoint I get Request and Response headers, and everything works as expected.
- the machine is reachable from my server, though there is a problem visible when I use
wget
to connect to it (see below) Unable to establish SSL connection. - The problem is also visible with openssl connections (see below)
- 我正在
Soapclient
基于我在本地拥有的 wsdl创建一个 PHP 。 - 如果我更改端点,我会得到请求和响应标头,一切都按预期工作。
- 该机器可以从我的服务器访问,但在我
wget
用来连接它时出现问题(见下文)无法建立 SSL 连接。 - openssl 连接也可以看到这个问题(见下文)
What I tried.
我试过的。
There are a lot of topics about "no connection!", but there is obviously a lot of "my router was bad, I made a typo in the address etc" going on. I did try these settings that were suggested multiple times, but more as a "cut'n'paste" solution to be sure It didn't work" then out of real reasoning. Some comments from me added
有很多关于“无连接!”的话题,但显然有很多“我的路由器坏了,我在地址中打错了字等”。我确实尝试了多次建议的这些设置,但更多的是作为“剪切和粘贴”解决方案以确保它不起作用“然后出于真正的推理。我补充说一些评论
Creating a stream_context
for the wsdl options. I have tried
stream_context
为 wsdl 选项创建一个。我试过了
$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;
(first only the ssl
options with verify_peer
and allow_self_signed
. Then I added the https
array, then finally I added the ciphers
key to ssl
.)
(首先只有ssl
带有verify_peer
和的选项allow_self_signed
。然后我添加了https
数组,最后我将ciphers
键添加到了ssl
。)
I found a reference to this bug, but 1) I'm not getting that warning, 2) it seems to be proxy-related and 3) My version shouldn't have the bug anymore. I'm running php 5.3.10
我找到了对这个错误的引用,但是 1) 我没有收到那个警告,2) 它似乎与代理相关,3) 我的版本不应该再有这个错误了。我在跑php 5.3.10
When I try to wget the url, I get:
当我尝试 wget 网址时,我得到:
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
If I try to connect with openssl, I get this:
如果我尝试与 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:
but if I force ssl3, I get an expected result
但是如果我强制使用 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. **
I have tried to add the curl-wrapper from this questionwith ssl_version set to 3 (as this seems to work on the openssl
command above). That wrapper does discard some of the parameters, so I'm not sure how complete this would be. Further, I still get a handshake error, unless I explicitly set checking to false. If I do that (see below), I get an empty response.
我试图从这个问题中添加 curl-wrapper并将 ssl_version 设置为 3 (因为这似乎适用于openssl
上面的命令)。该包装器确实丢弃了一些参数,所以我不确定这将有多完整。此外,我仍然会收到握手错误,除非我明确将检查设置为 false。如果我这样做(见下文),我会得到一个空的回应。
curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, false);
Causes
原因
As said above, I suspect the ssl handshake, but I have no clue how to fix it. I don't suspect issues with the wsdl or the client-creation, as the connection does work with another wsdl, the same wsdl with a different location set etc. It is purely this (https) endpoint that's giving me headaches.
如上所述,我怀疑 ssl 握手,但我不知道如何修复它。我不怀疑 wsdl 或客户端创建的问题,因为连接确实与另一个 wsdl、具有不同位置集的相同 wsdl 等一起工作。纯粹是这个 (https) 端点让我头疼。
Extra tests.
额外的测试。
Just as the test above with the curl wrapper I tried sending a minimal soap envelope as @halfwarr seemed to suggest in the comments. Als returns an empty response.
正如上面使用 curl 包装器进行的测试一样,我尝试发送一个最小的肥皂信封,正如@halfwarr 似乎在评论中所建议的那样。Als 返回空响应。
So with above it seems that I do have a method to squeeze an http 204
out of the server, but that's hardly success. But it could be a second problem? Not sure.
因此,上面似乎我确实有一种方法可以http 204
从服务器中挤出一个,但这几乎没有成功。但这可能是第二个问题吗?没有把握。
I am supposing that I need to try and force the ssl3, but I have no idea how (and this could be the wrong path as well so I'm trying to not have an XY problemhere :)
我假设我需要尝试强制 ssl3,但我不知道如何(这也可能是错误的路径,所以我试图在这里没有XY 问题:)
回答by Matheno
Interesting. Try adding this:
有趣的。尝试添加这个:
wget https://[[SERVER]]/soap/ —post-file=request.xml —header=”Content-Type: text/xml” -O response.xml
This will save the result as a file named response.xml.
这会将结果保存为名为 response.xml 的文件。
回答by rdizzle
The latest version PHP 5.5.3 will allow you to set the SSL Version. I've seen others that have been able to use a stream_context but, I was unable to get that work as well.
最新版本的 PHP 5.5.3 将允许您设置 SSL 版本。我见过其他人已经能够使用 stream_context 但是,我也无法完成这项工作。
As a work around and fail safe, I used a catch to grab the soap envelope request (similar to what you tested above):
作为一种解决方法和故障安全,我使用了一个 catch 来抓取肥皂信封请求(类似于你上面测试的内容):
$xml = $client->__getLastRequest()
and send via curl:
并通过 curl 发送:
curl_setopt($ch, CURLOPT_SSLVERSION, 3);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
That's allowing me to at least move forward.
这让我至少可以向前迈进。
回答by Sid
Have you enabled php_openssl.dll
in your php.ini
?
你启用php_openssl.dll
了php.ini
吗?
Reference:
参考: