摘要:
有没有办法强制PHP中内置的SoapClient类通过HTTPS连接到具有无效证书的服务器?
我为什么要这样做?
我已经在尚无 DNS 条目或证书的服务器上部署了新应用程序。我想在设置 DNS 条目并修复证书之前尝试使用 SoapClient 连接到它,最合理的方法似乎是让客户端在测试期间忽略证书。
难道我没有意识到这是一个巨大的安全风险吗?
这仅用于测试。当服务投入生产时,将有一个有效的证书,并且客户端将被强制验证它。
>SoapClient
在其参数中获取流上下文,您可以自己创建。这样,您几乎可以控制传输层的各个方面:
$context = stream_context_create([
'ssl' => [
// set some SSL/TLS specific options
'verify_peer' => false,
'verify_peer_name' => false,
'allow_self_signed' => true
]
]);
$client = new SoapClient(null, [
'location' => 'https://...',
'uri' => '...',
'stream_context' => $context
]);
文档:
- stream_context_create(( 文档
- HTTP 上下文选项文档
- SSL 上下文选项文档
接受的答案有效,但仅在非 WSDL 模式下有效。如果您尝试在 WSDL 模式下使用它(即传递 WSDL 文件 url 作为第一个参数(,您将面临下载 WSDL 文件时忽略流上下文的事实。因此,如果 WSDL 文件也位于证书损坏的服务器上,它将失败,很可能会将消息抛failed to load external entity
。在此处和此处查看更多信息。
正如建议的那样,最简单的解决方法是手动下载 WSDL 文件并将本地副本传递给 SoapClient。例如,您可以使用与接受答案相同的流上下文file_get_contents
下载它。
请注意,在创建 SoapServer 时,您还必须执行此操作。
PHP 5.6.8 的正确列表是
'ssl' => array('verify_peer_name'=>false, 'allow_self_signed' => true),
"verify_peer"=>false,
"verify_peer_name"=>false,
这适用于 php 5.6.x;
$arrContextOptions=stream_context_create(array(
"ssl" => array(
"verify_peer" => false,
"verify_peer_name" => false,
)));
$this->client = new SoapClient("https://tests.com?WSDL",
array(
//"soap_version" => SOAP_1_2,
"trace" => 1, // enable trace to view what is happening
"exceptions" => 0, // disable exceptions
"cache_wsdl" => 0, // disable any caching on the wsdl, encase you alter the wsdl
"stream_context" => $arrContextOptions
)
);
或者如果你愿意,你可以添加到cyrpto方法
$arrContextOptions=stream_context_create(array(
"ssl"=>array(
"verify_peer"=>false,
"verify_peer_name"=>false,
'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT
));