2011-12-13 48 views
1

我需要在Django中作为我们需要的自定义身份验证系统的一部分进行API调用(各种)。用户名和密码通过SSL发送到特定的URL(对这些参数使用GET),并且响应应该是包含带有用户信息的XML的正文的HTTP 200“OK”响应。Django中的urllib2/pycurl:获取XML,检查HTTP状态,检查HTTPS连接

如果验证失败,它将返回HTTP 401“未授权”响应。

为了安全起见,我需要检查:

  1. 请求被通过HTTPS连接
  2. 服务器证书的公钥的预期值(我使用“证书钉扎”,以抵御破匹配发送CA)

这是可能的python/django使用pycurl/urllib2或任何其他方法?

回答

3

使用M2Crypto

from M2Crypto import SSL 
ctx = SSL.Context('sslv3') 
ctx.set_verify(SSL.verify_peer | SSL.verify_fail_if_no_peer_cert, depth=9) 
if ctx.load_verify_locations('ca.pem') != 1: 
    raise Exception('No CA certs') 

c = SSL.Connection(ctx) 
c.connect(('www.google.com', 443)) # automatically checks cert matches host 
c.send('GET/\n') 
c.close() 

使用urllib2_ssl(不用说,但要明确:需要您自担风险使用它):

import urllib2, urllib2_ssl 

opener = urllib2.build_opener(urllib2_ssl.HTTPSHandler(ca_certs='ca.pem')) 
xml = opener.open('https://example.com/').read() 

相关:Making HTTPS Requests secure in Python

使用pycurl

c = pycurl.Curl() 
c.setopt(pycurl.URL, "https://example.com?param1=val1&param2=val2") 
c.setopt(pycurl.HTTPGET, 1) 
c.setopt(pycurl.CAINFO, 'ca.pem') 
c.setopt(pycurl.SSL_VERIFYPEER, 1) 
c.setopt(pycurl.SSL_VERIFYHOST, 2) 
c.setopt(pycurl.SSLVERSION,  3)  
c.setopt(pycurl.NOBODY, 1) 
c.setopt(pycurl.NOSIGNAL, 1) 
c.perform() 
c.close() 

要实现 '证书拼接' 不同的领域提供不同的'ca.pem'

+0

使用pycurl看起来似乎!这是一个可怕的包装,但它做到了这一点,而且比其他替代方案更加强大。现在测试它,它似乎工作(即将添加CURLOPT_CERTINFO支持,但似乎并没有与pycurl行为)。 – 2011-12-14 03:14:03

0

httplib2可以做HTTPS请求与证书验证:

import httplib2 
http = httplib2.Http(ca_certs='/path/to/cert.pem') 
try: 
    http.request('https://...') 
except httplib2.SSLHandshakeError, e: 
    # do something 

只要确保你的httplib2的是最新的。与我的发行版(Ubuntu 10.04)一起发货的那个没有ca_certs参数。

也在类似的问题给你的there is an example of certificate validation with pycurl

+1

据我了解,`httplib2`使用默认的`ssl`模块,它不在Python 2.x中执行任何主机名验证 – jfs 2011-12-14 00:37:36