我想让Python urllib.request.urlopen(url, ca*)
执行证书检查,但忽略主机名不匹配。替换opener for urllib.request.urlopen(url,ca *)
(这是必要的,因为主机可能通过公共IP,私有IP,主机名或FQDN来访问,我不想依赖证书上有所有有效字段)
根据官方文档,我可以使用自定义的揭幕战与HTTPSHandler
禁用主机名检查(https://docs.python.org/3/library/urllib.request.html)
然而,由于Python的Issue18543(http://bugs.python.org/issue18543),urllib.request.urlopen()
如果指定任何CA *参数会忽略安装了开门红。
我的问题是:
解决此问题的最佳方法是什么?我应该尝试覆盖urllib.request.urlopen()
方法吗?如果是这样,这是如何以pythonic方式完成的? 有没有其他的选择?我不想重写和维护很多基本代码。
到目前为止我的代码(不工作)低于:
import ssl
import urllib.request # used to be import urllib2 in python 2.x
#create an HTTPS Handler that does not check the hostname
https_handler = urllib.request.HTTPSHandler(debuglevel=0, check_hostname=False)
opener = urllib.request.build_opener(https_handler)
urllib.request.install_opener(opener)
# PROBLEM is that this opener will not be used by urlopen.
# solution: override the urlopen method?
# verify server certificate
try:
urllib.request.urlopen("https://127.0.0.1:4443", cafile="cert.pem")
except ssl.CertificateError as e:
print ("Certificate Error:",e)
return -1
return 0
运行代码给出了关于主机名不匹配证书错误。
这个问题也已经在这里讨论: http://www.gossamer-threads.com/lists/python/bugs/1005966?do=post_view_threaded
,特别是这篇文章提出一个解决办法: http://www.gossamer-threads.com/lists/python/bugs/1006048?do=post_view_threaded#1006048