web-dev-qa-db-fra.com

Connexion à https Host with soapclient: comment résoudre les problèmes de SSL?

TLDR

Je n'arrive pas à me connecter à un point de terminaison https avec un SoapClient. Comme mon wget retourne un handshake failure, je suppose que c'est la cause.

Comment puis-je faire une demande SOAP à ce serveur avec PHP?

achevée

J'essaie de me connecter à un serveur SOAP (https). Il ne dispose pas d'authentification par certificat client, la connexion devrait donc être assez simple, mais malheureusement, ce n'est pas le cas.

Le problème est que je continue à recevoir des messages Could not connect to Host.

La méthode de connexion que j'utilise fonctionne pour un autre serveur et j'ai vérifié que l'emplacement de ce serveur était correctement défini (je l'ai changé pour un serveur que je contrôle et que la réponse est affichée). Je soupçonne que le problème vient de la connexion https/ssl au serveur.

Situation

  • Je crée un PHP Soapclient basé sur un WSDL que j'ai localement.
  • Si je change de terminal, les en-têtes de demande et de réponse apparaissent et tout fonctionne comme prévu.
  • la machine est accessible depuis mon serveur, bien qu'un problème soit visible lorsque j'utilise wget pour me connecter (voir ci-dessous) Impossible d'établir une connexion SSL.
  • Le problème est également visible avec les connexions openssl (voir ci-dessous)

Ce que j'ai essayé.

Il y a beaucoup de sujets sur "pas de connexion!", Mais il y a évidemment beaucoup de "mon routeur était mauvais, j'ai fait une faute de frappe à l'adresse, etc.". J'ai essayé ces réglages qui ont été suggérés à plusieurs reprises, mais plutôt comme une solution "cut'n'paste" pour être sûr que cela ne fonctionnait pas ", alors que je n'avais pas vraiment raisonné. Quelques commentaires de ma part ont été ajoutés

Création d'un stream_context pour les options wsdl. j'ai essayé

$context = stream_context_create(
              array(
                'ssl' => array(
                           'verify_peer' => false,  //default
                           'allow_self_signed' => true, //needs verify peer, tried that
                           'ciphers'=>"SHA1", // quite random.
                   ),
                'https' => array(
                           'curl_verify_ssl_peer'  => false,
                           'curl_verify_ssl_Host'  => false
                          )
      )
            );
$options['stream_context'] = $context;

(D'abord, seules les options ssl avec verify_peer et allow_self_signed. Ensuite, j'ai ajouté le tableau https, puis j'ai finalement ajouté la clé ciphers à ssl.)

J'ai trouvé une référence à ce bogue , mais 1) je ne reçois pas cet avertissement, 2) il semble être lié au proxy et 3) ma version ne devrait plus avoir le bogue. Je cours php 5.3.10

Quand j'essaye de wget l'url, je reçois:

    wget https://[[servername]]/SOAP
    Resolving [[servername]] ([[servername]])... xxx.xxx.xxx.xxx
    Connecting to [[servername]]([[servername]])|xxx.xxx.xxx.xxx|:443... connected.
    OpenSSL: error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure

Si j'essaie de me connecter à openssl, j'obtiens ceci:

$ openssl s_client -connect [[server]]:443 -state
CONNECTED(00000003)
SSL_connect:before/connect initialization
SSL_connect:unknown state
SSL3 alert read:fatal:handshake failure
SSL_connect:error in unknown state
3074463944:error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure:s23_clnt.c:724:

mais si je force ssl3, j'obtiens un résultat attendu

$ openssl s_client -ssl3 -connect [[server]]:443 -state
CONNECTED(00000003)
SSL_connect:before/connect initialization
SSL_connect:SSLv3 write client hello A
SSL_connect:SSLv3 read server hello A
**happy certificate stuff. this is good**
Protocol  : SSLv3
Cipher    : DHE-RSA-AES256-SHA
**more happy certificate stuff. **

J'ai essayé d'ajouter le curl-wrapper de cette question avec ssl_version défini sur 3 (car cela semble fonctionner avec la commande openssl ci-dessus). Cette enveloppe supprime certains paramètres, je ne suis donc pas sûr que ce soit complet. De plus, je reçois toujours une erreur de négociation, à moins que je mette explicitement la vérification sur false. Si je le fais (voir ci-dessous), je reçois une réponse vide.

curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, false);

Les causes

Comme indiqué ci-dessus, je soupçonne la poignée de main SSL, mais je ne sais pas comment le réparer. Je ne soupçonne pas de problèmes avec wsdl ou la création de client, car la connexion fonctionne avec un autre wsdl, le même wsdl avec un jeu d'emplacement différent, etc. C'est purement ce terminal (https) qui me donne mal à la tête.

Tests supplémentaires.

Juste comme le test ci-dessus avec l'emballage de boucle, j'ai essayé d'envoyer une enveloppe de savon minimale comme @halfwarr semblait suggérer dans les commentaires. Als renvoie une réponse vide.

Donc, avec ce qui précède, il semble que j’ai une méthode pour extraire un http 204 du serveur, mais c’est loin d’être un succès. Mais cela pourrait être un deuxième problème? Pas certain.

Je suppose que je dois essayer de forcer le SS3, mais je n'ai aucune idée de comment (et cela pourrait aussi être le mauvais chemin alors j'essaie de ne pas avoir un problème XY ici :)

12
Nanne

Intéressant. Essayez d'ajouter ceci:

wget https://[[SERVER]]/soap/ —post-file=request.xml —header=”Content-Type: text/xml” -O response.xml

Cela enregistrera le résultat dans un fichier nommé response.xml.

1
Matheno

La dernière version PHP 5.5.3 vous permettra de définir la version SSL. J'ai vu d'autres personnes qui ont pu utiliser un stream_context mais je n'ai pas pu obtenir ce travail également. 

En guise de solution de contournement et d’échec, j’ai utilisé une prise pour saisir la demande d’enveloppe de savon (semblable à ce que vous avez testé ci-dessus): 

$xml = $client->__getLastRequest()

et envoyer via curl: 


curl_setopt($ch, CURLOPT_SSLVERSION, 3);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

Cela me permet au moins d'aller de l'avant. 

1
rdizzle

Avez-vous activé php_openssl.dll dans votre php.ini?

Référence:

PHP SOAP ne peut pas se connecter à une source WSDL SSL

0
Sid