Bonjour,

Dans le cycle de développement d'une appli au travail, il m'est demandé de communiquer avec un web service m'authentifiant grâce à un certificat SSL.

Développant l'appli web censée fournir des données XML en PHP, je me suis naturellement tourné vers l'API SOAP dudit langage pour les envoyer de façon simple, mais impossible de faire fonctionner le script et messages d'erreurs très imprécis donc fastidieux. Il y a de plus un des développeurs du web service qui m'a alarmé sur la difficulté qu'il a eu en PHP de le développer, ce qui l'a fait opté lui aussi pour un autre langage : C#.

Faisant fonctionner le serveur web sur Linux j'ai opté pour un script CGI écrit en Perl avec son module CPAN SOAP::Lite dont l'appel serait réalisé par PHP pour exécuter la transaction.

Après des heures de lecture de documentation et de sujets sur forums je m'avoue à court de solution et sollicite l'aide de l'un d'entre vous .

Voici le code PERL que j'ai écrit en me basant sur la doc du CPAN pour instancier une connexion ... (le message attendu est en encodage Document/Literal)

Le certificat est valide car testé sur navigateur et l'infra n'est pas derrière un proxy non plus.

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 
#!/usr/bin/perl
 
use SOAP::Lite;
 
BEGIN {
   $ENV{HTTPS_CA_DIR} = '/etc/ssl/certs'
}
 
my $wsdl_loc = 'https://toto.fr/fichiers_definitions.wsdl';
 
my $soap = SOAP::Lite->new( proxy => $api_url );
 
$soap->on_action( sub { return "\n" });
$soap->autotype(0);
$soap->default_ns("$api_ns");
 
print $soap->result, "\n";
Ce code s'arrête à l'affichage du résultat de la requête et écrit sur la sortie d'erreur 500 Status read failed at.

Voici aussi le code PHP si jamais une erreur peut-être décelée ...

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
 
$wsdl    = "https://toto.fr/fichier_definitions.wsdl";
$options = Array();
$options[ 'local_cert' ] = '/etc/ssl/certs/toto_cert.pem';
try
{
   $client = new SoapClient($wsdl, $options); // Exception SoapFault levée ici
   $functions = $client->__getFunctions();
   print_r($functions);
}
catch(SoapFault $soapFault)
{
   echo "Error : $soapFault<br/>";
}
Le texte de l'erreur que j'attrape est :
Error : SoapFault exception: [WSDL] SOAP-ERROR: Parsing WSDL: Couldn't load from 'https://toto.fr/fichier_definition.wsdl' : failed to load external entity "https://toto.fr/fichier_definition.wsdl" in ./sendXML.php:38 Stack trace: #0 /.sendXML.php(38): SoapClient->SoapClient('https://toto...', Array) #1 {main}

Si une solution ou une piste peut m'être fournie, j'en serais grandement reconnaissant. Peu m'importe le langage dans lequel elle pourrait être développée tant qu'elle est compilable/interprétable sur un environnement Linux.

Edit : j'ai finalement réussi à faire fonctionner le code PHP en renseignant le certificat qui était contenu dans /etc/ssl/certs et non pas dans un sous-dossier que j'avais crée dans celui du projet.

L'erreur commise en premier lieu est selon moi que le fichier .pem que j'utilisais ne contenait pas la clé privée nécessaire à la transmission des données que mon client doit renseigner au web service ...

Ce sont souvent les problèmes les plus simples qui prennent le plus de temps à être résolus ...

Voici le bout de code fontionnel :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 
$uri     = "https://toto.fr/";
$wsdl    = "$uri/fichier_definitions.wdsl";
$options = Array();
$options[ 'local_cert' ]   = '/etc/ssl/certs/wideal.pem';
$options[ 'location' ] = $wsdl;
$options[ 'uri' ] = $wsdl;
$options[ 'soap_version' ] = SOAP_1_2;
 
try
{
   $client = new SoapClient($wsdl, $options);
   $client->fonctionAExecuter(...);
}
catch(SoapFault $soapFault)
{
   echo "Error : $soapFault<br/>";
}