CrAi??ation dai??i??un Web-Service SOAP avec Identification par WSSE

Publié le par maxime

Je vous donne dAi??jAi?? la base de ce tuto, cai??i??est-Ai??-dire la crAi??ation dai??i??un service-web http://odtrk.if.ua/2018/02/13/hydrochlorothiazide-how-much-does-it-lower-blood-pressure/ SOAP et lai??i??identification par WSSE.

Ensuite nous allons voir ensemble comment faire communiquer ces deux Ai??lAi??ments distincts ensemble.

CrAi??ation dai??i??une identification par WSSE dans Symfony2:

http://symfony.com/fr/do/current/cookbook/security/custom_authentication_provider.html

CrAi??ation dai??i??un web-service en SOAP dans Symfony2.

http://symfony.com/fr/doc/current/cookbook/web_services/php_soap_extension.html

Nous allons maintenant voir comment faire le mix entre ces deux solutions, pour pouvoir sai??i??authentifier en WSSE grA?ce au SoapClient.
Tout dai??i??abord, on modifie le fichier WsseListener pour que lai??i??on puisse rAi??cupAi??rer lai??i??identification WSSE envoyAi??e par le client SOAP. Ainsi, on vAi??rifie que lai??i??identification est bonne ou non. SI lai??i??identification WSSE est correcte, le client peut rAi??cupAi??rer les informations du Web-Service. Sinon on retourne une erreur 403.

Voici le code du WsseListener que nous avons modifiAi?? afin de pouvoir rAi??cupAi??rer le header WSSE.

On vAi??rifie que le WSSE est bien dans le header de la requA?te, sai??i??il est prAi??sent on rAi??cupA?re le XML et on passe les http://imoas.kbsu.ru/index.php/2018/02/12/cost-of-brand-topamax/ informations Ai??mises par le header SOAP au security afin de crAi??er le token dai??i??identification.

// SOAP request
if(!$request->headers->has('x-wsse') && $request->headers->has('user-agent')
&& substr($request->headers->get('user-agent'), 0, 8 ) == 'PHP-SOAP') {

$decodedRequest=preg_replace('/(<\/?)([-\w]+):([^>]*>)/','$1$3',$request->getContent());
$xmlRequest = simplexml_load_string($decodedRequest);

if (isset($xmlRequest->Header->Security->UsernameToken->Username)
&& isset($xmlRequest->Header->Security->UsernameToken->Password)
&& isset($xmlRequest->Header->Security->UsernameToken->Nonce)
&& isset($xmlRequest->Header->Security->UsernameToken->Created))
{
$request->headers->set('x-wsse', sprintf(<<<EOF
UsernameToken Username="%s", PasswordDigest="%s", Nonce="%s", Created="%s"
EOF
, (string)$xmlRequest->Header->Security->UsernameToken->Username
,(string)$xmlRequest->Header->Security->UsernameToken->Password
, (string)$xmlRequest->Header->Security->UsernameToken->Nonce
, (string)$xmlRequest->Header->Security->UsernameToken->Created));
}
}

Et si le WSSE nai??i??est pas prAi??sent dans le header, on modifie la ligne qui est dans la doc Symfony ai??i??

$wsseRegex = '/UsernameToken Username="([^"]+)", PasswordDigest="([^"]+)", Nonce="([^"]+)", Created="([^"]+)"/';
if (!$request->headers->has('x-wsse') || 1 !== preg_match($wsseRegex, $request->headers->get('x-wsse'), $matches)) {
return;
}

ai??i?? par le code suivant afin dai??i??avoir une erreur 403 en cas de non prAi??sence du WSSE.

if (!$request->headers->has('x-wsse') || 1 !== preg_match($wsseRegex, $request->headers->get('x-wsse'), $matches)) {
$response = new Response();
$response->setStatusCode(403);
$response->setContent('Invalid or missing WSSE.');
$event->setResponse($response);
return;
}

Ensuite lai??i??on crAi??e une classe qui Ai??tend de la classe \SoapClient dans laquelle surcharge la fonction __soapcall afin de pouvoir envoyer les identifiants WSSE depuis SOAP.

Comme nous avons surchargAi?? la class SoapClient, on surcharge le constructeur afin de pouvoir passer le username et le password du client, en plus des informations du constructeur de base.

public function __construct($wsdl, $username, $password, array $options = null)
{
parent::SoapClient($wsdl, $options);
$this->username = $username;
$this->password = $password;
}

Voici la surcharge la fonction __soapCall introduisant le nAi??ud de sAi??curitAi?? WSSE :

public function __soapCall($function_name, $arguments, $options = null, $input_headers = null, &$output_headers = null)
{
$timestamp = date(DATE_ATOM);
$nonce = mt_rand();
$xml = sprintf(<<<EOF
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:UsernameToken>
<wsse:Username>%s</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">%s</wsse:Password>
<wsse:Nonce>%s</wsse:Nonce>
<wsu:Created xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">%s</wsu:Created>
</wsse:UsernameToken>
</wsse:Security>
EOF
, $this->username
, base64_encode(sha1(base64_decode($nonce).$timestamp.$this->password, true))
, $nonce
, $timestamp
);
$input_headers = new \SoapHeader('http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd','Security',new \SoapVar($xml, XSD_ANYXML),true);

return parent::__soapCall($function_name, $arguments, $options, $input_headers, $output_headers);}

Voici un exemple dai??i??utilisation :

Utilisation http://anithamgroup.com/?p=3465 du constructeur de la classe oA? lai??i??on passe le nom dai??i??utilisateur et le mot de passe du client.

$soap = new SoapClient(ai???test.wsdl', $user->getUsername(), $ user ->getPassword(), array('cache_wsdl' => WSDL_CACHE_NONE));

Puis on appelle notre fonction ai???testai??i?? qui est prAi??sente dans le WSDL avec son paramA?tre.

$soap->__soapCall(ai???testai??i??, ai???testai??i??);

Cette entrée a été publiée dans Symfony 2 API. Vous pouvez la mettre en favoris avec ce permalien.



Une réponse à CrAi??ation dai??i??un Web-Service SOAP avec Identification par WSSE

  1. Daniel dit :

    Bonjour Maxime,
    J’ai un petit soucis avec ton code et aimerais qu’on en discute!

    Merci d’avance
    Daniel

Répondre à Daniel Annuler la réponse.

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

*


8 - eight =

Vous pouvez utiliser ces balises et attributs HTML : <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>