开发者

Making SOAP-call in PHP and setting SSL version

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?

Input开发者_如何转开发s, please?

(Using Ubuntu Linux, PHP 5.3.3)


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


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


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!


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


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


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 . '"')
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜