Effettuare chiamate SOAP in PHP e impostare la versione SSL

Ho realizzato diversi script che funzionano con WSDL esterno. Ne ho incontrato uno che devo integrare nel nostro sistema che non riesco a mettermi al lavoro. Ho provato per una settimana senza risultati.

Lo script ha esito negativo durante la creazione del constructor:

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

Dà l'errore:

 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" 

Ho installato e installato openssl con PHP, e ricordo che ho già altre chiamate SOAP funzionanti ad altre WSDL su SSL. Ho scoperto che non posso risolvere questo con un certificato perché non funziona già al constructor.

Ma: ho provato a connettermi al server remoto con la row di command openssl, e anche questo command non è riuscito:

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

Ma poi ho provato a forzarlo su SSL3 e ha funzionato perfettamente, come questo:

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

Quindi questo mi ha fatto pensare che wherevo abbinare la versione SSL del server remoto. Per il doppio controllo ho anche provato a creare una connessione cURL tramite PHP e non è riuscito fino a quando non ho aggiunto la forzatura della versione SSL in questo modo:

 curl_setopt($ch, CURLOPT_SSLVERSION, 3); 

L'aggiunta di CURLOPT_SSLVERSION alla connessione cURL ha reso tutto ok. E poi la radice della mia domanda:

Come faccio a forzare PHP constructor di soap / chiamata per usare anche SSL3. Mi sembra che questa dovrebbe essere la soluzione. Ma non sono stato in grado di scoprire come impostare la function SOAP PHP per utilizzare solo SSL3. Dato che sia la commandline -openssl- che PHP cURL funzionano con SSL3 forzato, suppongo che la stessa cosa succederebbe con la mia function SOAP?

Input, per favore?

(Uso di Ubuntu Linux, PHP 5.3.3)

Ho avuto lo stesso problema, il seguente wrapper l'ha risolto (ho dovuto forzare 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. se non riesce a scaricare la parte del file WSDL, quindi scaricare manualmente il WSDL (ad esempio con arricciatura) e utilizzare quel file localmente. IMHO __doRequest non viene chiamato mentre si trova nella fase di download di WSDL.

 file_put_contents(dirname(__FILE__) .'/Server.wsdl',get_wsdl()); //get_wsdl uses the same wrapper as above $oWS = new StupidWrapperForOracleServer(dirname(__FILE__) .'/Server.wsdl',arrays('trace'=>1,'cache_wsdl'=>0)); 

A partire da PHP 5.5.0, credo che tu possa fare

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

Invece di creare un wrapper, puoi provare ad aggiungere i seguenti frammenti di codice?

 $stream_opts = arrays( // 'ssl'=>arrays('ciphers'=>"3DES" // also working // further ciphers on http://www.openssl.org/docs/apps/ciphers.html 'ssl'=>arrays('ciphers'=>"SHA1" ) ); $myStreamContext = stream_context_create($stream_opts); $soapOptions['stream_context'] = $myStreamContext; $soapClient = new SoapAuthClient("https://...", $soapOptions); 

In bocca al lupo!

Prova 'sslv3: // webtjener09 ….' o usa una class wrapper in cui puoi impostare l'opzione CURL richiesta.

Se si utilizza Oracle Weblogic 11g per ospitare i servizi Web in SSL, assicurarsi di utilizzare l'implementazione SSL basata su JSSE.

Accedere a Weblogic Console e andare su Server -> (il proprio server) -> Configurazione-> SSL-> Avanzate e select la casella di controllo Usa SSL JSSE .

Ulteriori informazioni sono disponibili nei manuali di Weblogic

Stai attento se usi il set di caratteri utf-8.
Questa soluzione funziona bene, ma devi dichiarare il set di caratteri nell'intestazione Curl.

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