Foros del Web » Programando para Internet » Python »

Cliente SOAP web services compatible con HTTPS y firma digital

Estas en el tema de Cliente SOAP web services compatible con HTTPS y firma digital en el foro de Python en Foros del Web. Buenas tardes, Llevo navegando todos los días desde hace un mes en busca de una librería o módulo que trabaje con protocolos SOAP con el ...
  #1 (permalink)  
Antiguo 29/06/2015, 07:35
 
Fecha de Ingreso: junio-2012
Ubicación: Barcelona
Mensajes: 12
Antigüedad: 11 años, 10 meses
Puntos: 1
Cliente SOAP web services compatible con HTTPS y firma digital

Buenas tardes,
Llevo navegando todos los días desde hace un mes en busca de una librería o módulo que trabaje con protocolos SOAP con el fin de consumir web services de terceros a través de protocolo seguro.

Objetivo:
- Encontrar un cliente SOAP para PYTHON que permita conexiones HTTPS.
- Poder firmar las peticiones con un certificado digital.


Problemas:
He probado bastantes librerías como suds, pysimplesoap y otras, con todas me falla en el momento de instanciar el cliente porque no es capaz de abrir una conexión sobre una URL con protocolo de seguridad HTTPS.

Este es el error que más me suelo encontrar:
Código:
IOError: Error reading file '/path/libreria/soap/usando': failed to load external entity '/path/libreria/soap/usando'
Este caso no solo me pasa con Python, también con PHP, ¿puede deberse a una falta de configuración de SSL? ¿O quizás tiene que ver con el certificado?


¿Conocen alguna solución para consumir web services con HTTPS? ¿Y alguna librería para firmar el xml con un certificado que sea compatible con lo anterior?

Espero que puedan ayudarme porque este tema me tiene loquísimo y no veo la hora de terminar.
Muchas gracias y saludos.

PD: Si lo que me recomiendan es que abandone Python para los web services, se aceptan sugerencias de otros lenguajes/librerías, siempre que sean de uso gratuito.
  #2 (permalink)  
Antiguo 29/06/2015, 18:35
Avatar de razpeitia
Moderador
 
Fecha de Ingreso: marzo-2005
Ubicación: Monterrey, México
Mensajes: 7.321
Antigüedad: 19 años, 1 mes
Puntos: 1360
Respuesta: Cliente SOAP web services compatible con HTTPS y firma digital

Yo he usado suds y me ha funcionado bien.

http://stackoverflow.com/questions/6...ttps-with-cert
  #3 (permalink)  
Antiguo 30/06/2015, 02:42
 
Fecha de Ingreso: junio-2012
Ubicación: Barcelona
Mensajes: 12
Antigüedad: 11 años, 10 meses
Puntos: 1
Respuesta: Cliente SOAP web services compatible con HTTPS y firma digital

Cita:
Iniciado por razpeitia Ver Mensaje
Yo he usado suds y me ha funcionado bien.

[url]http://stackoverflow.com/questions/6277027/suds-over-https-with-cert[/url]
Hola razpeitia,
suds es con el que más lo he intentado pero sin suerte.

A continuación realizaré una prueba con el mismo código que se muestra en el link que me pasas para ver si podemos solucionarlo a nivel de suds.

Especificaciones:
- SO: Debian 8.1
- Python: 2.7.9
- Suds 0.4
- Uso de entorno virtual de Python para el proyecto
- Firma digital (no auth con certificado sino token WS-SECURITY en las cabeceras del XML), creo que se puede realizar con "SudsSigner" si consigo hacer funcionar suds primero.

Resultados:

El primer error:
Código:
Traceback (most recent call last):
  File "webservices.py", line 76, in <module>
    client = Client(WSDL, location=URL)  #, transport=transport)
  File "/home/www/virtualenv/ws_test/local/lib/python2.7/site-packages/suds/client.py", line 112, in __init__
    self.wsdl = reader.open(url)
  File "/home/www/virtualenv/ws_test/local/lib/python2.7/site-packages/suds/reader.py", line 152, in open
    d = self.fn(url, self.options)
  File "/home/www/virtualenv/ws_test/local/lib/python2.7/site-packages/suds/wsdl.py", line 136, in __init__
    d = reader.open(url)
  File "/home/www/virtualenv/ws_test/local/lib/python2.7/site-packages/suds/reader.py", line 79, in open
    d = self.download(url)
  File "/home/www/virtualenv/ws_test/local/lib/python2.7/site-packages/suds/reader.py", line 95, in download
    fp = self.options.transport.open(Request(url))
  File "/home/www/virtualenv/ws_test/local/lib/python2.7/site-packages/suds/transport/https.py", line 60, in open
    return  HttpTransport.open(self, request)
  File "/home/www/virtualenv/ws_test/local/lib/python2.7/site-packages/suds/transport/http.py", line 62, in open
    return self.u2open(u2request)
  File "/home/www/virtualenv/ws_test/local/lib/python2.7/site-packages/suds/transport/http.py", line 118, in u2open
    return url.open(u2request, timeout=tm)
  File "/usr/lib/python2.7/urllib2.py", line 431, in open
    response = self._open(req, data)
  File "/usr/lib/python2.7/urllib2.py", line 449, in _open
    '_open', req)
  File "/usr/lib/python2.7/urllib2.py", line 409, in _call_chain
    result = func(*args)
  File "/usr/lib/python2.7/urllib2.py", line 1240, in https_open
    context=self._context)
  File "/usr/lib/python2.7/urllib2.py", line 1197, in do_open
    raise URLError(err)
urllib2.URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:581)>
Este error parece estar en las versiones de Python 2.7.9 en adelante, al parecer no es capaz de encontrar los certificados CA del pc, lo he intentado incluso especificando la ruta completa al CA pero no lo detecta. Así que para solucionarlo ignoramos la verificación del CERT CA, cosa que me gustaría poder corregir en un futuro, si alguna sabe como configurar correctamente Python para que detecte bien los CA se lo agradecería.


Para arreglar el problema expuesto arriba, aplico el siguiente código de prueba del que he eliminado las URLS por motivos de privacidad, reemplazenlas con cualquier URL de Web services en https:

Código:
# -*- coding: utf-8 -*-
from suds.client import Client
from suds.transport.http import HttpTransport, Reply, TransportError
import urllib2, httplib, socket
import ssl
from httplib import HTTPConnection, HTTPS_PORT


HOST = "webservices.es"
URL = "https://%s/ws/i01/gapt/00001" % HOST
WSDL = "%s?wsdl" % URL


class HTTPSConnection(httplib.HTTPConnection):
    default_port = HTTPS_PORT

    def __init__(self, host, port=None, key_file=None, cert_file=None,
            strict=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT,
            source_address=None):
        HTTPConnection.__init__(self, host, port, strict, timeout,
                source_address)
        self.key_file = key_file
        self.cert_file = cert_file

    def connect(self):
        sock = socket.create_connection((self.host, self.port),
                self.timeout, self.source_address)
        if (self._tunnel_host):
            self.sock = sock
            self._tunnel()
        self.sock = ssl.wrap_socket(sock, self.key_file, self.cert_file, ssl_version=ssl.PROTOCOL_TLSv1)


class HTTPSHandler(urllib2.HTTPSHandler):
    def __init__(self):
        urllib2.HTTPSHandler.__init__(self)

    def https_open(self, req):
        return self.do_open(self.getConnection, req)

    def getConnection(self, host, timeout=300):
        context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
        context.verify_mode = ssl.CERT_NONE
        context.check_hostname = False
        return httplib.HTTPSConnection(host, context=context)


class HttpsTransport(HttpTransport):
    def __init__(self, **kwargs):
        HttpTransport.__init__(self, **kwargs)
        self.handler = HTTPSHandler()
        self.urlopener = urllib2.build_opener(self.handler)

    def open(self, request):
        return HttpTransport.open(self, request)

    def send(self, request):
        return HttpTransport.send(self, request)


import logging
logging.basicConfig(level=logging.INFO)
logging.getLogger('suds.client').setLevel(logging.DEBUG)
logging.getLogger('suds.transport').setLevel(logging.DEBUG)
logging.getLogger('suds.xsd.schema').setLevel(logging.DEBUG)
logging.getLogger('suds.wsdl').setLevel(logging.DEBUG)


if (__name__ == '__main__'):
    transport = HttpsTransport()
    client = Client(WSDL, location=URL, transport=transport)  # Aquí falla
    print(client)

Este código da como resultado lo siguiente:
Código:
DEBUG:suds.wsdl:reading wsdl at: https://webservices.es/ws/i01/gapt/00001?wsdl ...
DEBUG:suds.transport.http:opening (https://webservices.es/ws/i01/gapt/00001?wsdl)
Traceback (most recent call last):
  File "webservices.py", line 76, in <module>
    client = Client(WSDL, location=URL, transport=transport)
  File "/home/www/virtualenv/ws_test/local/lib/python2.7/site-packages/suds/client.py", line 112, in __init__
    self.wsdl = reader.open(url)
  File "/home/www/virtualenv/ws_test/local/lib/python2.7/site-packages/suds/reader.py", line 152, in open
    d = self.fn(url, self.options)
  File "/home/www/virtualenv/ws_test/local/lib/python2.7/site-packages/suds/wsdl.py", line 136, in __init__
    d = reader.open(url)
  File "/home/www/virtualenv/ws_test/local/lib/python2.7/site-packages/suds/reader.py", line 79, in open
    d = self.download(url)
  File "/home/www/virtualenv/ws_test/local/lib/python2.7/site-packages/suds/reader.py", line 95, in download
    fp = self.options.transport.open(Request(url))
  File "Adam.py", line 58, in open
    return HttpTransport.open(self, request)
  File "/home/www/virtualenv/ws_test/local/lib/python2.7/site-packages/suds/transport/http.py", line 64, in open
    raise TransportError(str(e), e.code, e.fp)
Esto es lo más lejos que he podido llegar, si alguien me puede guiar para solucionarlo estaría muy agradecido.

Saludos y gracias

Etiquetas: cliente, compatible, firma, https, services, soap
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 02:26.