Я пытаюсь использовать SOAP-сервис с помощью PHP SOAP-клиента, но он не работает с сообщением:
SoapFault: SOAP-ERROR: Parsing WSDL: Couldn't load from 'https://domain.com/webservice.asmx?wsdl' : failed to load external entity "https://domain.com/webservice.asmx?wsdl"\n in /Users/andrewdchancox/Projects/test/testsoap.php on line 10
Я загрузил файл wsdl и служил ему из локального экземпляра apache и загружал его без каких-либо проблем. Единственное, что я могу подумать, это то, что веб-служба работает через SSL с самоподписанным сертификатом – когда я wget wsdl получаю следующую ошибку:
--2012-09-11 16:28:39-- https://domain.com/webservice.asmx?wsdl Resolving domain.com (domain.com)... 11.111.111.11 Connecting to domain.com (domain.com)|11.111.111.11|:443... connected. ERROR: The certificate of 'domain.com' is not trusted. ERROR: The certificate of 'domain.com' hasn't got a known issuer.
Я googled вокруг и тщательно прочитал документы PHP для клиента PHP SOAP – http://php.net/manual/en/class.soapclient.php и его конструктор – http://www.php.net/manual/ en / soapclient.soapclient.php и не нашел ничего, чтобы помочь.
У кого-нибудь есть идеи?
Это было два года назад, но я думаю, что он заслуживает ответа.
Класс SoapClient в PHP использует потоки PHP для связи через HTTP. По разным причинам SSL через потоки PHP небезопасны 1 , но в этом случае ваша проблема в том, что она слишком безопасна.
Первым шагом к решению является использование параметра stream_context
при создании вашего SoapClient 2 . Это позволит вам указать более сложные настройки SSL 3 :
// Taken from note 1 below. $contextOptions = array( 'ssl' => array( 'verify_peer' => true, 'cafile' => '/etc/ssl/certs/ca-certificates.crt', 'verify_depth' => 5, 'CN_match' => 'api.twitter.com', 'disable_compression' => true, 'SNI_enabled' => true, 'ciphers' => 'ALL!EXPORT!EXPORT40!EXPORT56!aNULL!LOW!RC4' ) ); $sslContext = stream_context_create($contextOptions); // Then use this context when creating your SoapClient. $soap = new SoapClient('https://domain.com/webservice.asmx?wsdl', array('stream_context' => $sslContext));
Идеальное решение вашей проблемы – создать свой собственный сертификат ЦС, использовать его для подписания сертификата SSL и добавить сертификат CA в cafile
. Еще лучше, может быть, иметь только этот сертификат в cafile
, чтобы избежать cafile
, чтобы какой-либо изгоев CA подписывал чужой сертификат для вашего домена, но это не всегда будет практичным.
Если то, что вы делаете, не обязательно должно быть безопасным (например, во время тестирования), вы также можете использовать настройки SSL в контексте потока, чтобы снизить безопасность вашего соединения. Опция allow_self_signed
позволит самоподписанные сертификаты:
$contextOptions = array( 'ssl' => array( 'allow_self_signed' => true, ) ); $sslContext = stream_context_create($contextOptions); $soap = new SoapClient('https://domain.com/webservice.asmx?wsdl', array('stream_context' => $sslContext));
Ссылки: