HTTPS Client Authentication solution for the Suds SOAP library
We recently came upon the need for a Python SOAP client library that supported SSL client authentication (client-side certificates). When surveying the various options, we liked SOAPpy, but it had a bug in its support for SOAP complex types that required us to switch to Suds, which is also a very nice framework.
Suds does not support client certificates directly, and neither does urllib2, the URL-opener library it depends on. However, httplib, which is used at the core, does support HTTPS client authentication. Fortunately, somebody found a workaround for urllib2, and we were able to combine that with a trick of our own to integrate it with Suds. Here it is:
import httplib
import urllib2
from suds.transport import HttpTransport
from suds.client import Client
from suds.options import Options
def getClient(url, key, cert):
transport = HttpClientAuthTransport(key, cert)
return Client(url, transport = transport)
#SUDS Client Auth solution
class HttpClientAuthTransport(HttpTransport):
def __init__(self, key, cert, options = Options()):
HttpTransport.__init__(self, options)
self.urlopener = urllib2.build_opener(HTTPSClientAuthHandler(key, cert))
#HTTPS Client Auth solution for urllib2, inspired by
# http://bugs.python.org/issue3466
# and improved by David Norton of Three Pillar Software. In this
# implementation, we use properties passed in rather than static module
# fields.
class HTTPSClientAuthHandler(urllib2.HTTPSHandler):
def __init__(self, key, cert):
urllib2.HTTPSHandler.__init__(self)
self.key = key
self.cert = cert
def https_open(self, req):
#Rather than pass in a reference to a connection class, we pass in
# a reference to a function which, for all intents and purposes,
# will behave as a constructor
return self.do_open(self.getConnection, req)
def getConnection(self, host):
return httplib.HTTPSConnection(host, key_file=self.key, cert_file=self.cert)
You can use this with PEM-encoded key and certificate files:
client = getClient('https://localhost/soap/services/Service?wsdl','keyFileName','certFileName')
client.service.doSomething("Hello World")
This makes communicating with a PKI-protected SOAP service easy. However, there is an important thing to note! httplib does not support server certificate verification, which means that it simply trusts the server certificate no matter who it was signed by, if it is expired, or if it matches the domain that you are connecting to. I did some searching, but the most I can determine right now is that this is a known issue in Python and has not yet been fixed.
Good luck! Client certificate authentication is a powerful security measure, and it is important that client applications support it. This is one step in the right direction.
- dnorton's blog
- Login to post comments

