python - headers - urllib2 timeout
Usando certificados de cliente con urllib2 (4)
Necesito crear un canal seguro entre mi servidor y un servicio web remoto. Usaré HTTPS con un certificado de cliente. También necesitaré validar el certificado presentado por el servicio remoto.
¿Cómo puedo usar mi propio certificado de cliente con urllib2?
¿Qué debo hacer en mi código para garantizar que el certificado remoto sea correcto?
Aquí hay un error en el bugtracker oficial de Python que parece relevante y tiene un parche propuesto.
Debido a que la respuesta de alex es un enlace, y el código en esa página está mal formateado, solo voy a poner esto aquí para la posteridad:
import urllib2, httplib
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, timeout=300):
return httplib.HTTPSConnection(host, key_file=self.key, cert_file=self.cert)
opener = urllib2.build_opener(HTTPSClientAuthHandler(''/path/to/file.pem'', ''/path/to/file.pem.'') )
response = opener.open("https://example.org")
print response.read()
Según la respuesta de Antoine Pitrou al problema vinculado en la respuesta de Hank Gay, esto se puede simplificar un poco (a partir de 2011) mediante el uso de la biblioteca ssl
incluida:
import ssl
import urllib.request
context = ssl.create_default_context()
context.load_cert_chain(''/path/to/file.pem'', ''/path/to/file.key'')
opener = urllib.request.build_opener(urllib.request.HTTPSHandler(context=context))
response = opener.open(''https://example.org'')
print(response.read())
(Código de Python 3, pero la biblioteca ssl
también está disponible en Python 2).
La función load_cert_chain
también acepta un parámetro de contraseña opcional, lo que permite el cifrado de la clave privada.