PHP + WS + Autenticación + SSL

Estos días por unos u otros motivos me ha tocado desarrollar un par de clientes para conectar a servicios web en diferentes tecnologías. Los servicios web están hechos en Java, pero van a ser consumidos desde diferentes plataformas y lenguajes, y me ha tocado a mí escribir el código de estos primeros clientes. Uno de ellos lo he desarrollado sobre PHP, y aunque he de decir que al principio ha sido muy fácil, la parte de SSL se me ha atragantado un poco ya que, pese a conseguir que la negociación entre cliente y servidor, y la obtención del WSDL se hiciera sobre “https”, la petición al servicio web y su respuesta se hacían sobre “http”. Así que con motivo de los quebraderos de cabeza que me ha dado esto, lo voy a dejar por escrito por tres razones: la primera es que no se me vuelva a olvidar, la segunda es que tanto yo como cualquiera de vosotros lo tenga a mano (creedme he llegado a la página 20 de la búsqueda de Google, jamás digáis que no hay nada interesante más haya de la página 4), y la tercera es que, algún día con más tiempo, me gustaría investigar que hace exactamente cada una de las propiedades que estoy utilizando y si se puede prescindir de alguna.

Antes de empezar, decir que estoy escribiendo todo esto partiendo de que tengo instalada una versión 5.3.18 de PHP, sobre todo lo digo porque, según entre que versiones, hay diferencias muy grandes. En principio, entre la 5.3 y la 5.4 no debería haber grandes diferencias. (la 5.5 está en alfa así que no se nada)

PHP + WS
Para empezar vamos a consumir un servicio web básico, sin autenticación ni SSL.

$wsdl = “http://server/webservice?wsdl”;
$client = new SoapClient($wsdl);
$result = $client->webservice($parameters);
print_r($result);

En la primera línea tenemos la dirección del fichero WSDL correspondiente al servicio web que queremos consumir.

En la segunda línea tenemos la creación del cliente a partir del WSDL que nos va a permitir utilizar los métodos ofertados por el servicio web.

En la tercera llamamos al método del servicio web que queremos utilizar pasándole un “array” con los parámetros que necesitemos.

En la cuarta simplemente escribimos el resultado.

PHP + WS + Autenticación
En el siguiente paso vamos añadir la parte de autenticación, es decir, pasar un usuario y contraseña al servidor para poder identificarnos en un sistema de control de acceso básico. El código será muy parecido, solo que ha la hora de crear el cliente con el método “SoapClient” le pasaremos estos credenciales.

$wsdl = “http://server/webservice?wsdl”;
$clientOptions = array(‘login’ => ’nuestroUser’, ‘password‘ => ‘nuestraContr’);
$client = new SoapClient($wsdl, $clientOptions);
$result = $client->webservice($parameters);
print_r($result);

Con esto conseguiremos identificarnos de forma exitosa en el servidor para poder utilizar los métodos ofertados por el servicio web.

PHP + WS + Autenticación + SSL
El tercer paso es añadir el soporte SSL. Aquí es donde yo me atasqué hasta que conseguí encontrar la combinación de parámetros adecuada. No se es la forma correcta o la más eficiente, pero si que por lo menos funciona. De hecho, podemos capturar el tráfico con una herramienta como WireShark o Network Monitor para comprobar que nuestras peticiones van cifradas. Para añadir la capacidad de realizar consultas sobre SSL bastará con añadir las siguientes propiedades al array de opciones que se le pasa al método SoapClient junto con el nombre de usuario y la contraseña.

$wsdl = “https://server/webservice?wsdl”;
$localCert = “certificado.pem”;
$clientOptions = array(‘login’ => ’nuestroUser’, ‘password‘ => ‘nuestraContr’,
                       ‘local_cert’ => $localCert, ‘passphrase’ => ‘contrCertificado’,
                       ‘soap_version’ => SOAP_1_1, ‘encoding’ => ‘UTF-8’,
                       ‘compression’ => (SOAP_COMPRESSION_ACCEPT | SOAP_COMPRESSION_GZIP),
                       ‘location’ => ‘urlWS’);
$client = new SoapClient($wsdl, $clientOptions);
$result = $client->webservice($parameters);
print_r($result);

login y password, son los credenciales para la autenticación.

local_cert, es el certificado que tendremos en nuestro sistema local para acceder al servidor a través de SSL.

passphrase, es la contraseña de dicho certificado.

soap_version, es la versión de soap que está usando el servidor (Es una constante PHP).

encoding, es la codificación que vamos a utilizar para la comunicación.

compression, es si aceptamos compresión o no y en que formatos.

location, es la url del servicio web, generalmente es como la del WSDL pero sin el “?wsdl”.

Con esto tendremos nuestro tráfico cifrado y podremos consultar sin problemas los métodos del servicio web sobre SSL.

Quede dicho que es post está hecho únicamente desde el punto de vista del programador, ni hemos explicado como habilitar SOAP o SSL en PHP ni como configurar nada, esto es lo primero que tendríais que revisar si tenéis algún problema.

Y para terminar, sé que el post no va muy el la línea de la serie de artículos que estábamos haciendo últimamente, pero lo que hace bonito el trabajo en parte es que nunca sabes a que problema te vas a enfrentar mañana. Nos vemos.

PHP + WS + Autenticación + SSL

20 thoughts on “PHP + WS + Autenticación + SSL

  1. Anonymous says:

    Que cambios hay del lado del la creación del Web Service para utilizar Autenticación y SSL? Tienes el ejemplo del webservice?

    Like

  2. Erick says:

    Que cambios hay del lado del la creación del Web Service para utilizar Autenticación y SSL? Tienes el ejemplo del webservice?

    Like

    1. svoboda says:

      Pues ahora mismo no tengo ningún ejemplo de código porque fue algo que tuve que buscar por motivos laborales y por razones obvias dicho código no lo puedo publicar.
      Lo que si que te puedo decir es que para el tráfico SSL hay que configurar el servidor para ello y generar los certificados adecuados. He hecho un par de búsquedas en google y hay bastante información sobre ello tanto para servidores PHP como Java (en mi caso era uno Java).
      Sobre la Autenticación me refiero a los métodos habituales “BASIC”, “DIGEST”… Esto se suele definir a nivel de programación o, si utilizas algún framework, en este, por ejemplo Spring Security.
      Respecto a crear el WS no requiere ningún cambio específico, este es igual sea la seguridad como sea, lo que cambian es las capas que hay hasta llegar a él.
      Espero que te sirva.

      Like

    1. svoboda says:

      Jajajaj, ahí llevas toda la razón. Se ve que se me colo al copiar de un ejemplo a otro el código para hacer el post. Fallo mio completamente. Gracias por el aviso, ahora lo actualizo. Pero funcionar, funciona, porque de ahí lo apliqué a una aplicación real en producción

      Like

      1. William says:

        una pregunta, y disculpa por la molestia, mi pregunta es : ¿puedo incluir una carpeta dentro de mi proyecto php que contenga un certificado? por ejemplo: una carpeta llamada ssl que contiene un certificado.crt y hacer la referencia $certificado = ‘../ssl/certificado.crt’; le agradezco mucho su tiempo gracias y una disculpa por ser tan molesto. SALUDOS 🙂

        Like

  3. svoboda says:

    No es molestia. Pues con un .crt, no lo he probado nunca no podría asegurarlo. Como ves en el ejemplo, y en módulos que he desplegado en otras ocasiones, siempre lo he hecho con los .pem, pero vamos, si tienes el .crt puedes transformarlo en un .pem.
    openssl x509 -in certificado.crt -out certificado.der -outform DER
    openssl x509 -in certificado.der -inform DER -out certificado.pem -outform PEM
    Debería de funcionarte.
    Si tienes que usar el .crt, pues tendrás que probarlo, y si te animas, puedes añadir un comentario con el resultado. Un saludo.

    Like

    1. svoboda says:

      Hola, no entiendo muy bien la pregunta. El último ejemplo es la conexión a un servidor con WS basados en SOAP sobre SSL. ¿Qué quieres? ¿Un ejemplo de servidor en vez de cliente? Un saludo.

      Like

      1. Jorge says:

        Hola Gracias Por tu aporte, yo soy nuevo en esto pero a mi me gustaría como un ejemplo del servidor, mas que todo como recibes el archivo .pem , Saludos

        Like

  4. edgar says:

    hola, tengo una duda, ay algun parametro donde le pueda assignar un tiempo de respuesta, esto es ya que cuando mando ejecutar el web service, pasado un determinado tiempo marca error, cuando el web service aun no ha regresado ninguna respuesta

    Like

  5. Sirclain says:

    Hola si este tema aun sigue activo, alquien me puede explicar por que me pasa esto:

    Fatal error: Uncaught SoapFault exception: [WSDL] SOAP-ERROR: Parsing WSDL: Couldn’t load from ‘https://ws.servidor?wsdl’ : Document is empty in C:\xampp2\htdocs\pruebas\ws\wom.php:2 Stack trace: #0 C:\xampp2\htdocs\pruebas\ws\wom.php(2): SoapClient->SoapClient(‘https://ws.wom….’) #1 {main} thrown in C:\xampp2\htdocs\pruebas\ws\wom.php on line 2

    lo que hago es

    $wsdl = “https://server/webservice?wsdl”;
    $localCert = “certificado.pem”;
    $clientOptions = array(‘login’ => ’nuestroUser’, ‘password‘ => ‘nuestraContr’,
    ‘local_cert’ => $localCert, ‘passphrase’ => ‘contrCertificado’,
    ‘soap_version’ => SOAP_1_1, ‘encoding’ => ‘UTF-8’,
    ‘compression’ => (SOAP_COMPRESSION_ACCEPT | SOAP_COMPRESSION_GZIP),
    ‘location’ => ‘urlWS’);
    $client = new SoapClient($wsdl, $clientOptions);
    $result = $client->webservice($parameters);
    print_r($result);

    Like

  6. frog69 says:

    alguien con quien platicar de este tema , perimero que nada se ulitiza, alguna libreria ? algun frame work para utilizar valiables como soapclien?

    Like

  7. fjavierm says:

    La variable “parameters” no es mas que un array con los parámetros necesarios para la llamada, algo así como:

    $parameters = array(‘p1’=>$1, ‘p2’=>$2);

    Like

    1. frog69 says:

      bueno tardes una mi duda es esta tengo que consumir servicio web proporcionado por sap

      “usuario”, “password” => “pass”);
      $client = new SoapClient($wsdl, $clientOptions); //enviamos los datos para conectarse al servicio
      $result = $client->webservice($parameters);// parameter es dato que nos sirve para trabajar, webservice es metodo que estamos ultisando de servicio
      print_r($result);// se imprime el resultado estoy en lo correcto

      ?
      >

      estoi en lo correcto disculpa es la primera ves que lo hago y no encuentro doucmentacion como consumir un servicio sap con un metodo muy simple

      Like

  8. Buenisimo este aporte! Estoy construyendo un AGI usando PHP y ha sido de gran utilidad este aporte.

    A la hora de consumir un servicio simple sin certificado a través del AGI me funciono perfecto.
    Pero quisiera saber si existirá algún servicio gratuito que tenga autenticacion para así realizar pruebas?

    Like

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.