pythonsslsuds

Bypass SSL when I'm using SUDS for consume web service


I'm using SUDS for consuming web service. I tried like bellow:

client = Client(wsdl_url)
list_of_methods = [method for method in client.wsdl.services[0].ports[0].methods]
print(list_of_methods)

I got this error:

urllib.error.URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:645)>

I saw link but it is just solution for python 2.7. How can I bypass SSL with SUDS? Or is there any none python solution (For example add fake certificate in windows OS)? I'm using python 3(So I have to use urllib instead of urllib2).


Solution

  • A suds client uses a subclass of suds.transport.Transport to process requests.

    The default transport used is an instance of suds.transport.https.HttpAuthenticated, but you can override this when you instantiate the client by passing a transport keyword argument.

    The http and https transports are implemented using urllib.request (or urllib2 for python2) by creating an urlopener. The list of handlers used to create this urlopener is retrieved by calling the u2handlers() method on the transport class. This means that you can create your own transport by subclassing the default and overriding that method to use a HTTPSHander with a specific ssl context, e.g:

    from suds.client import Client
    from suds.transport.https import HttpAuthenticated
    from urllib.request import HTTPSHandler
    import ssl
    
    class CustomTransport(HttpAuthenticated):
    
        def u2handlers(self):
    
            # use handlers from superclass
            handlers = HttpAuthenticated.u2handlers(self)
    
            # create custom ssl context, e.g.:
            ctx = ssl.create_default_context(cafile="/path/to/ca-bundle.pem")
            # configure context as needed...
            ctx.check_hostname = False
    
            # add a https handler using the custom context
            handlers.append(HTTPSHandler(context=ctx))
            return handlers
    
    # instantiate client using this transport
    c = Client("https://example.org/service?wsdl", transport=CustomTransport())