Reputation: 2147
I am making a client in php with soap for a webservice in .net. The webservice run over https with a self-signed certificate and for the tests I must trust this certificate without install it.
The problem is that I allways get this error:
SOAP-ERROR: Parsing WSDL: Couldn't load from 'https://winsystemsintl.com:54904/PSAService.svc?wsdl' : failed to load external entity "https://winsystemsintl.com:54904/PSAService.svc?wsdl".
Here is my code:
$opts = [
'ssl' => [
// set some SSL/TLS specific options
'verify_peer' => false,
'verify_peer_name' => false,
'allow_self_signed' => true
],
'http'=>[
'user_agent' => 'PHPSoapClient'
]
];
// Initialize Soap Client
$this->client = new SoapClient($this->wsdl, array('ssl_method' => SOAP_SSL_METHOD_SSLv3,'soap_version' => SOAP_1_2, 'location' => 'https://winsystemsintl.com:54904/PSAService.svc','stream_context' => stream_context_create($opts), 'exceptions' => true, 'trace' => true));
I was able to get the wsdl with wget:
wget --secure-protocol=SSLv3 https://winsystemsintl.com:54904/PSAService.svc?wsdl --no-check-certificate
Hope someone can help me, thanks a lot.
Upvotes: 2
Views: 6258
Reputation: 1025
The problem is that PHP ignores your stream context when downloading the WSDL
file. A workaround is to download the WSDL
file, and all the schema imports to your local file system (I'm using tidy
here to pretty print the XML):
wget --secure-protocol=SSLv3 https://winsystemsintl.com:54904/PSAService.svc?wsdl --no-check-certificate -O - | tidy -xml -indent > PSAService.svc?wsdl
wget --secure-protocol=SSLv3 https://winsystemsintl.com:54904/PSAService.svc?xsd=xsd0 --no-check-certificate -O - | tidy -xml -indent > PSAService.svc?xsd=xsd0
wget --secure-protocol=SSLv3 https://winsystemsintl.com:54904/PSAService.svc?xsd=xsd1 --no-check-certificate -O - | tidy -xml -indent > PSAService.svc?xsd=xsd1
wget --secure-protocol=SSLv3 https://winsystemsintl.com:54904/PSAService.svc?xsd=xsd2 --no-check-certificate -O - | tidy -xml -indent > PSAService.svc?xsd=xsd2
wget --secure-protocol=SSLv3 https://winsystemsintl.com:54904/PSAService.svc?xsd=xsd3 --no-check-certificate -O - | tidy -xml -indent > PSAService.svc?xsd=xsd3
Next, you have to edit PSAService.svc?wsdl
(the filename that wget saved to) and change the imports to point to your local system instead of the web. Use the replace-all feature in your favorite editor and replace 'https://winsystemsintl.com:54904/'
with ''
:
Example Before:
<wsdl:types>
<xsd:schema targetNamespace="http://tempuri.org/Imports">
<xsd:import schemaLocation="https://winsystemsintl.com:54904/PSAService.svc?xsd=xsd0"
namespace="http://tempuri.org/" />
<xsd:import schemaLocation="https://winsystemsintl.com:54904/PSAService.svc?xsd=xsd1"
namespace="http://schemas.microsoft.com/2003/10/Serialization/" />
<xsd:import schemaLocation="https://winsystemsintl.com:54904/PSAService.svc?xsd=xsd2"
namespace="http://schemas.datacontract.org/2004/07/PSA.Service.MessageObjects.Pregunta" />
<xsd:import schemaLocation="https://winsystemsintl.com:54904/PSAService.svc?xsd=xsd3"
namespace="http://schemas.datacontract.org/2004/07/PSA.Service.MessageObjects.Respuesta" />
</xsd:schema>
</wsdl:types>
After:
<wsdl:types>
<xsd:schema targetNamespace="http://tempuri.org/Imports">
<xsd:import schemaLocation="PSAService.svc?xsd=xsd0"
namespace="http://tempuri.org/" />
<xsd:import schemaLocation="PSAService.svc?xsd=xsd1"
namespace="http://schemas.microsoft.com/2003/10/Serialization/" />
<xsd:import schemaLocation="PSAService.svc?xsd=xsd2"
namespace="http://schemas.datacontract.org/2004/07/PSA.Service.MessageObjects.Pregunta" />
<xsd:import schemaLocation="PSAService.svc?xsd=xsd3"
namespace="http://schemas.datacontract.org/2004/07/PSA.Service.MessageObjects.Respuesta" />
</xsd:schema>
</wsdl:types>
Repeat for each of the files that were downloaded.
Next, change your code to the following (I assume here that all PHP/WSDL files are in the same folder):
$opts = [
'ssl' => [
// set some SSL/TLS specific options
'verify_peer' => false,
'verify_peer_name' => false,
'allow_self_signed' => true
],
'http'=>[
'user_agent' => 'PHPSoapClient'
]
];
// Initialize Soap Client
$client = new SoapClient('PSAService.svc?wsdl', array('ssl_method' => SOAP_SSL_METHOD_SSLv3,'soap_version' => SOAP_1_2, 'location' => 'https://winsystemsintl.com:54904/PSAService.svc','stream_context' => stream_context_create($opts), 'exceptions' => true, 'trace' => true));
var_dump($client->__getFunctions());
Now the SoapClient
has skipped downloading the WSDL
from the web, and you're ready to start making calls using your stream context.
Upvotes: 1