替换urllib.request.urlopen(url,ca *)的开启器

我试图让Pythonurllib.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 *参数它将忽略已安装的opener。

我的问题是:

解决此问题的最佳方法是什么?我应该尝试重写该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

看来这并不是一件容易的事,从长远来看,大多数解决方案都不可靠。

我想发布选择解决该问题的解决方案。

首先,我选择使用urllib3库(https://pypi.python.org/pypi/urllib3)。

从文档中,我发现最容易使用PoolManager:

import urllib3

http = urllib3.PoolManager(cert_reqs='CERT_REQUIRED',
                           ca_certs="cert.pem",
                           assert_hostname=False)
try:
    r = http.request('GET', 'https://127.0.0.1:4443/')
    print("STATUS:", r.status)
    print("Certificate verification NO HOSTNAME successful")

except urllib3.exceptions.SSLError as e:
    print ("SSL Error:", e)
    return -1

return 0

请注意,在urllib3版本1.10中将忽略assert_hostname = False:https : //github.com/shazow/urllib3/issues/524

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

带有验证的urllib.request.urlopen(url)

如何使用 urllib.request.urlopen 从多个 url 获取所有图像 url

urllib.request.urlopen(url) 在 python 3 中不起作用

kaggle内核:urllib.request.urlopen不适合任何URL

Python 3.6.2 url.request.urlopen() urllib.error.HTTPError:HTTP 错误 403:禁止

urllib.request.urlopen(url)如何通过IP地址使用此功能?

为什么有时urllib.request.urlopen不起作用,但浏览器起作用?

Python文档:urllib.request.urlopen(URL,data = None,[timeout,] *,cafile = None中的方括号是什么意思?

urllib,urllib2,urllib.request.open,AttributeError:“模块”对象没有属性“ urlopen”

HTTP错误401:未经授权使用urllib.request.urlopen

HTTPError问题:urllib.request.urlopen python请求错误

将 urllib.request.urlopen 移动到请求

python:urllib.request.urlopen不起作用

如何处理来自urllib.request.urlopen()的响应编码

模拟urllib.request.urlopen的read函数返回MagicMock签名

Python 3:urllib.request.urlopen和Progressbar

urllib.request 的 urlopen 无法在 python 3.7 中打开页面

urllib.request.urlopen 不适用于特定网站

Python urllib.request.urlopen:AttributeError:“ bytes”对象没有属性“ data”

Python请求lib工作,urllib.request.urlopen POST不工作

urllib.request.urlopen返回字节,但是我无法对其进行解码

urllib.request.urlopen无法获取堆栈溢出选举的主要页面

我需要使用urllib2.Request / urlopen处理哪些错误/异常?

为什么在这种情况下urllib.request.urlopen会阻塞?

python3中来自urllib.request的urlopen的奇怪行为

python3 安全问题,os.system('wget...') 与 urllib.request.urlopen(...)

urllib.request.urlopen 的行为很奇怪。第二天不返回数据。为什么?

urllib.error.HTTPError: HTTP Error 404: Not Found when using request.urlopen()

为什么urllib.request.urlopen在《华尔街日报》的网站上给我404?