Cómo autenticar usuarios en WebServices SOAP

Muchas organizaciones (Especialmente gubernamentales) optan por exponer sus servicios web mediante el protocolo SOAP.

Para hacer uso de dichos servicios es necesario consumirlos.

Existen algunas ocasiones en las que no basta con conocer la URL del servicio, también es necesario realizar algún tipo de autenticación para obtener el resultado buscado.

Autenticación HTTP en WebServices SOAP

El método más simple de autenticación es el propio de HTTP.

Si este es el caso, basta con generar una URL del estilo http://usuario@password:dominio/web_service para poder acceder.

El principal problema de este método es su poca seguridad, ya que las credenciales viajan en cada pedido, por lo tanto, es bastante poco frecuente su uso en servicios web.

En aplicaciones web normales podrías llegar a encontrártelo (o incluso podrías querer implementarlo).

API-Key en WebServices SOAP

Una segunda forma de realizar autenticación es aquella basada en las API-Keys.

En este escenario, el proveedor del servicio debe decirte cuál es tu clave, la cual deberás enviar mediante algún encabezado como parte de tu petición.

Para ello, asumiendo que utilices la clase SoapClient, deberás crear un nuevo contexto en el que basar tus peticiones, algo como:

$soapclient = new SoapClient($wsdl, [ 
    'stream_context' => stream_context_create([ 
     'http'=> [ 
      'header' => "X-Api-Key: 1234abcd"    
     ] 
    ]) 
]); 

Este esquema es algo más seguro, siempre y cuando se realice la comunicación a través de SSL.

Autenticación via encabezados SOAP

Otro esquema que suele utilizarse es el de la autenticación mediante encabezados SOAP.

Este método permite que las credenciales viajen como parte del mensaje enviado lo cual puede ser deseable para evitar depender del protocolo subyacente (HTTP en la mayoría de los casos).

Para lograrlo debes usar el método __setSoapHeaders y la clase SoapHeader.

Ejemplo:

$header = new SoapHeader(
                   $namespace,
                   'UserCredentials'
                   [
                         $UserID,
                         $Pwd
                   ]
);

$client->__setSoapHeaders($header);

Claro que tanto el namespace como el nombre y estructura exacta del encabezado deberás validarlo contra el archivo WSDL del servicio al que te quieras conectar, pero la adaptación es simple.

Autenticación vía WSSE

Por último hay que mencionar un protocolo especial de seguridad para servicios web: WSSE (o WS-Security).

Este protocolo es bastante complejo ya que incluye, entre otros, firmas digitales.

Desafortunadamente, a la fecha no existe una implementación nativa de PHP para este tipo de autenticación, con lo cual no queda mucha opción que crear la nuestra o usar alguna desarrollada por un tercero.

El punto clave aquí es hacer algunos toques a los encabezados que enviaremos.

Para ello una buena opción es extender la clase SoapHeader de esta forma:

class WsseAuthHeader extends SoapHeader 
{
    private $wss_ns = 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd';

    function __construct($user, $pass, $ns = null) 
    {
        if ($ns) {
            $this->wss_ns = $ns;
        }

       $auth = new stdClass();
       $auth->Username = new SoapVar($user, XSD_STRING, NULL, $this->wss_ns, NULL, $this->wss_ns); 
       $auth->Password = new SoapVar($pass, XSD_STRING, NULL, $this->wss_ns, NULL, $this->wss_ns);

       $username_token = new stdClass();
       $username_token->UsernameToken = new SoapVar($auth, SOAP_ENC_OBJECT, NULL, $this->wss_ns, 'UsernameToken', $this->wss_ns); 

       $security_sv = new SoapVar(
           new SoapVar($username_token, SOAP_ENC_OBJECT, NULL, $this->wss_ns, 'UsernameToken', $this->wss_ns),
           SOAP_ENC_OBJECT, NULL, $this->wss_ns, 'Security', $this->wss_ns);
       parent::__construct($this->wss_ns, 'Security', $security_sv, true);
    }
}

Y luego simplemente se trata de agregar este nuevo encabezado a nuestro cliente:

$client->__setSoapHeaders(new WsseAuthHeader( $UserID, $PWD));

Y a partir de aquí ya es posible consumir los servicios con normalidad.

mchojrin

¿Te quedó alguna duda? Publica aca tu pregunta

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.

A %d blogueros les gusta esto: