13

I've made several scripts working with external WSDL. I have encountered one I have to integrate into our system that I can't get to work. I'be been trying for a week without any result.

The script fails on creating the constructor already:

$client = new SoapClient("https://webtjener09.kred.no/TestWebservice/OppdragServiceSoapHttpPort?WSDL");

Gives the error:

PHP Fatal error:  SOAP-ERROR: Parsing WSDL: Couldn't load from 'https://webtjener09.kred.no/TestWebservice/OppdragServiceSoapHttpPort?WSDL' : failed to load external entity "https://webtjener09.kred.no/TestWebservice/OppdragServiceSoapHttpPort?WSDL"

I do have openssl installed and working with PHP, and remember that I already have other working SOAP-calls to other WSDL's over SSL. I found out that I can not solve this with a cert either since it fails already at the constructor.

But: I tried to connect to the remote server with openssl command line, and this command also failed:

openssl s_client -connect webtjener09.kred.no:443 -state

But then I tried forcing it to SSL3 and it worked perfectly, like this:

openssl s_client -ssl3 -connect webtjener09.kred.no:443 -state

So that got me thinking that I had to match the SSL version of the remote server. To doublecheck I also tried making a cURL connection via PHP and it failed until I added forcing of SSL version like this:

curl_setopt($ch, CURLOPT_SSLVERSION, 3);

Adding CURLOPT_SSLVERSION to the cURL connection made it ok. And then the root of my question:

How do I force PHP soap constructor/call to use SSL3 as well. It seems to me that this would have to be the solution. But I haven't been able to find out how to set the PHP SOAP function to use SSL3 only. Since both commandline -openssl- and PHP cURL work with SSL3 forced, then I presume the same thing would happen with my SOAP-function?

Inputs, please?

(Using Ubuntu Linux, PHP 5.3.3)

skoTner
  • 168
  • 1
  • 1
  • 9
  • Since PHP 5.5.0 It's possible to set SSL_METHOD for SoapClient, but if there is problem on trying to get WSDL file, It has to be downloaded manually via cURL for example. – Adrian Modliszewski Apr 09 '14 at 10:18

6 Answers6

11

I had the same problem, the following wrapper solved it (i had to force SSL2)

class StupidWrapperForOracleServer extends SoapClient {
  protected function callCurl($url, $data, $action) {
     $handle   = curl_init();
     curl_setopt($handle, CURLOPT_URL, $url);
     curl_setopt($handle, CURLOPT_HTTPHEADER, Array("Content-Type: text/xml", 'SOAPAction: "' . $action . '"'));
     curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
     curl_setopt($handle, CURLOPT_POSTFIELDS, $data);
     curl_setopt($handle, CURLOPT_SSLVERSION, 2);
     $response = curl_exec($handle);
     if (empty($response)) {
       throw new SoapFault('CURL error: '.curl_error($handle),curl_errno($handle));
     }
     curl_close($handle);
     return $response;
   }

   public function __doRequest($request,$location,$action,$version,$one_way = 0) {
       return $this->callCurl($location, $request, $action);
   }
 }

Btw. if it fails at the downloading the WSDL file part, then download the WSDL manually (with curl for example), and use that file locally. IMHO __doRequest is not called while in the WSDL downloading stage.

file_put_contents(dirname(__FILE__) .'/Server.wsdl',get_wsdl()); //get_wsdl uses the same wrapper as above
$oWS = new StupidWrapperForOracleServer(dirname(__FILE__) .'/Server.wsdl',array('trace'=>1,'cache_wsdl'=>0));
Berdir
  • 6,881
  • 2
  • 26
  • 38
SztupY
  • 10,291
  • 8
  • 64
  • 87
5

As of PHP 5.5.0, I believe you can do

$client = new SoapClient("https://webtjener09.kred.no/TestWebservice/OppdragServiceSoapHttpPort?WSDL", array(
    'ssl_method' => SOAP_SSL_METHOD_SSLv3
));
Keith
  • 1,352
  • 3
  • 21
  • 48
  • Can you please elaborate a bit your suggestion by explaining the benefit of SOAP_SSL_METHOD_SSLv3? What about the difference with SOAP_SSL_METHOD_SSLv23 or not providing any method at all? – edigu Nov 08 '18 at 12:45
3

Instead of creating a wrapper, can you try to add the following code fragments?

$stream_opts = array(
//      'ssl'=>array('ciphers'=>"3DES" // also working
//      further ciphers on http://www.openssl.org/docs/apps/ciphers.html
        'ssl'=>array('ciphers'=>"SHA1"
      )
);

$myStreamContext = stream_context_create($stream_opts);
$soapOptions['stream_context'] = $myStreamContext;
$soapClient = new SoapAuthClient("https://...", $soapOptions);

Good luck!

Community
  • 1
  • 1
Tontaube
  • 59
  • 2
1

Try 'sslv3://webtjener09....' or use a wrapper class where you can set the required cURL option.

rik
  • 8,592
  • 1
  • 26
  • 21
0

If you are using Oracle Weblogic 11g to host your web services under SSL, make sure you are using the JSSE-Based SSL Implementation.

Log into the Weblogic Console, and go to Server->(your server)->Configuration->SSL->Advanced and check the Use JSSE SSL check box.

More information can be found in the Weblogic Manuals

mavroprovato
  • 8,023
  • 5
  • 37
  • 52
0

Be careful if you use utf-8 charset.
This solution works well, but you must declare the charset in header Curl.

curl_setopt($handle, CURLOPT_HTTPHEADER, Array("Content-Type: text/xml; charset = utf-8", 'SOAPAction: "' . $action . '"')