Reputation: 2340
I'm trying to consume a SOAP service using the PHP SOAP client but it fails with the message:
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
I've downloaded the wsdl file and served it from a local instance of apache and it loads without any issues. The only thing I can think it could be is that the web service is running over SSL with a self signed certificate - when I wget the wsdl I get the following error:
--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.
I've googled around and thoroughly read the PHP docs for the PHP SOAP client - http://php.net/manual/en/class.soapclient.php and it's constructor - http://www.php.net/manual/en/soapclient.soapclient.php and not found anything to help.
Anyone got any ideas?
Upvotes: 4
Views: 8408
Reputation: 7315
This was two years ago but I think it deserves an answer.
The SoapClient class in PHP uses PHP streams to communicate over HTTP. For various reasons SSL over PHP streams is insecure1, but in this case your problem is that it's too secure.
The first step towards a solution is to use the stream_context
option when constructing your SoapClient2. This will allow you to specify more advanced SSL settings3:
// 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));
The ideal solution to your problem is to create your own CA certificate, use that to sign the SSL certificate, and add your CA certificate to the cafile
. Even better might be to only have that certificate in the cafile
, to avoid some rogue CA signing someone else's certificate for your domain, but that won't always be practical.
If what you are doing does not need to be secure (such as during testing), you can also use SSL settings in a stream context to reduce the security of your connection. The option allow_self_signed
will allow self-signed certificates:
$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));
Links:
Upvotes: 7