在 PHP SoapClient 中禁用证书验证

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8443618/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 04:43:32  来源:igfitidea点击:

Disable certificate verification in PHP SoapClient

phpsoapsslhttpssoap-client

提问by MW.

Summary:
Is there a way to force the built in SoapClient-class in PHP to connect over HTTPS to a server with an invalid certificate?

总结:
有没有办法强制 PHP 中的内置 SoapClient 类通过 HTTPS 连接到具有无效证书的服务器?

Why would I want to do that?
I have deployed a new application on a server that has no DNS entry or certificate yet. I want to try connecting to it with a SoapClient beforesetting up the DNS entry and fixing the certificate, and the most reasonable way to do this seems to be to just make the client ignore the certificate during testing.

我为什么要这样做?
我在没有 DNS 条目或证书的服务器上部署了一个新应用程序。我想设置 DNS 条目和修复证书之前尝试使用 SoapClient 连接到它,最合理的方法似乎是让客户端在测试期间忽略证书。

Don't I realise that this is a huge security risk?
This is only for testing. When the service goes into production, there will be a valid certificate in place, and the client will be forced to validate it.

难道我没有意识到这是一个巨大的安全风险吗?
这仅用于测试。当服务投入生产时,将有一个有效的证书,并且客户端将被迫对其进行验证。

回答by Kaii

SoapClienttakes a stream contextin its parameters, which you can create yourself. That way you can control almost every aspect of the transport layer:

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
]);

Documentation:

文档:

回答by tobik

The accepted answer works but only in the non-WSDLmode. If you try to use this in the WSDLmode (i. e. you pass a WSDL file url as the first argument) you will face the fact that the stream context is ignored when downloading WSDL files. So if the WSDL file is also located on a server with broken certificate, it will fail, most likely throwing the message failed to load external entity. See more hereand here.

接受的答案有效,但仅适用于非 WSDL模式。如果您尝试在WSDL模式下使用它(即您将 WSDL 文件 url 作为第一个参数传递),您将面临这样一个事实,即下载 WSDL 文件时流上下文被忽略。因此,如果 WSDL 文件也位于证书损坏的服务器上,它将失败,很可能会抛出消息failed to load external entity在此处此处查看更多信息

As suggested, the simplest way around is to download the WSDL file manually and pass the local copy to the SoapClient. You can download it for example with file_get_contentsusing the very same stream context from the accepted answer.

正如所建议的,最简单的方法是手动下载 WSDL 文件并将本地副本传递给 SoapClient。例如,您可以file_get_contents使用与接受的答案完全相同的流上下文来下载它。

Note that you will also have to do this when creating a SoapServer.

请注意,您还必须在创建 SoapServer 时执行此操作。

回答by Will T

The correct list for PHP 5.6.8 is

PHP 5.6.8 的正确列表是

'ssl' => array('verify_peer_name'=>false, 'allow_self_signed' => true),