在PHP中进行SOAP调用并设置SSL版本

时间:2011-01-18 08:11:57

标签: php soap ssl curl wsdl

我已经使用外部WSDL编写了几个脚本。我遇到了一个我必须整合到我的系统中,我无法工作。我一直在努力,没有任何结果。

脚本在创建构造函数时失败:

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

给出错误:

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"

我确实安装了openssl并使用PHP,并且记住我已经通过SSL对其他WSDL进行了其他工作的SOAP调用。我发现我无法使用证书来解决这个问题,因为它已经在构造函数中失败了。

可是: 我尝试使用openssl命令行连接到远程服务器,此命令也失败了:

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

但后来我尝试将它强制转换为SSL3并且它完美运行,如下所示:

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

这让我觉得我必须匹配远程服务器的SSL版本。要进行双重检查,我还尝试通过PHP建立cURL连接失败,直到我添加强制SSL版本为止:

curl_setopt($ch, CURLOPT_SSLVERSION, 3);

将CURLOPT_SSLVERSION添加到cURL连接使其正常。然后是我的问题的根源:

如何强制PHP soap构造函数/调用也使用SSL3。在我看来,这必须是解决方案。但是我还没有找到如何将PHP SOAP函数设置为仅使用SSL3。既然命令行-openssl-和PHP cURL都强制使用SSL3,那么我认为我的SOAP函数也会发生同样的事情?

请输入?

(使用Ubuntu Linux,PHP 5.3.3)

6 个答案:

答案 0 :(得分:11)

我有同样的问题,以下包装解决了它(我必须强制使用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);
   }
 }

顺便说一下。如果它在下载WSDL文件部分时失败,则手动下载WSDL(例如使用curl),并在本地使用该文件。在WSDL下载阶段,不会调用IMHO __doRequest。

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

答案 1 :(得分:5)

从PHP 5.5.0开始,我相信你可以做到

$client = new SoapClient("https://webtjener09.kred.no/TestWebservice/OppdragServiceSoapHttpPort?WSDL", array(
    'ssl_method' => SOAP_SSL_METHOD_SSLv3
));

答案 2 :(得分:2)

您可以尝试添加以下代码片段而不是创建包装器吗?

$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);
祝你好运!

答案 3 :(得分:1)

尝试'sslv3:// webtjener09 ....'或使用wrapper class,您可以在其中设置所需的cURL选项。

答案 4 :(得分:0)

如果您使用Oracle Weblogic 11g在SSL下托管您的Web服务,请确保您使用的是基于JSSE的SSL实现。

登录Weblogic控制台,然后转到Server->(您的服务器) - > Configuration-> SSL-> Advanced并选中使用JSSE SSL 复选框。

可以在Weblogic Manuals

中找到更多信息

答案 5 :(得分:0)

如果使用utf-8字符集,请小心 此解决方案效果很好,但您必须在标题Curl中声明charset。

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