如何在请求python中禁用主机名检查

use*_*498 7 python ssl python-requests

我正在使用Requests连接到RESTful API.我想要达到的服务器使用自带证书的ssl.

cafile = "gateway.pem"
r = requests.get(request, auth=('admin', 'password'), verify=cafile)
Run Code Online (Sandbox Code Playgroud)

问题是我得到主机名不匹配的SSLError.应该有一种方法来禁用主机名检查而不禁用证书验证,就像在许多java实现中一样,但我无法找到如何在python中处理请求.

堆栈跟踪:

Traceback (most recent call last):
  File "<pyshell#43>", line 1, in <module>
    r = requests.get(request, auth=("admin", "password"), verify='gateway.pem')
  File "C:\Python27\lib\site-packages\requests-2.0.0-py2.7.egg\requests\api.py", line 55, in get
    return request('get', url, **kwargs)
  File "C:\Python27\lib\site-packages\requests-2.0.0-py2.7.egg\requests\api.py", line 44, in request
    return session.request(method=method, url=url, **kwargs)
  File "C:\Python27\lib\site-packages\requests-2.0.0-py2.7.egg\requests\sessions.py", line 357, in request
    resp = self.send(prep, **send_kwargs)
  File "C:\Python27\lib\site-packages\requests-2.0.0-py2.7.egg\requests\sessions.py", line 460, in send
    r = adapter.send(request, **kwargs)
  File "C:\Python27\lib\site-packages\requests-2.0.0-py2.7.egg\requests\adapters.py", line 358, in send
    raise SSLError(e)
SSLError: hostname '10.76.92.70' doesn't match u'lital.com'
Run Code Online (Sandbox Code Playgroud)

如何才能做到这一点?

t-8*_*8ch 9

请求不允许直接,但您可以提供使用基础功能的自定义传输适配器urllib3.请求文档中介绍了传输适配器的用法.

此代码未经过测试,但应该可以使用.

from requests.adapters import HTTPAdapter
from requests.packages.urllib3.poolmanager import PoolManager


# Never check any hostnames
class HostNameIgnoringAdapter(HTTPAdapter):
    def init_poolmanager(self, connections, maxsize, block=False):
        self.poolmanager = PoolManager(num_pools=connections,
                                       maxsize=maxsize,
                                       block=block,
                                       assert_hostname=False)


# Check a custom hostname
class CustomHostNameCheckingAdapter(HTTPAdapter):
    def cert_verify(self, conn, url, verify, cert):
        #      implement me
        host = custom_function_mapping_url_to_hostname(url)
        conn.assert_hostname = host
        return super(CustomHostNameCheckingAdapter,
                     self).cert_verify(conn, url, verify, cert)
Run Code Online (Sandbox Code Playgroud)

详细信息该assert_hostname参数的工作方式如下:如果None使用URL中的主机名,则False禁止主机名检查,如果自定义字符串验证此字符串.

  • 我正在这样做:s = requests.Session()s.mount('https://',MyAdapter())r = s.get(request,auth =("admin","admin"),验证=凭证档案错误) (2认同)

lan*_*ane 5

我参加聚会有点晚了,但是requests_toolbelt如果您安装版本0.7.0或更高版本(我的ubuntu 16.04仅具有0.6.0),看起来可能会有所帮助:https : //toolbelt.readthedocs.io/en/latest/adapters .html#hostheaderssladapter

从链接:

Example usage:
>>> s.mount('https://', HostHeaderSSLAdapter())
>>> s.get("https://93.184.216.34", headers={"Host": "example.org"})
Run Code Online (Sandbox Code Playgroud)


m.w*_*ski -5

http://docs.python-requests.org/en/latest/user/advanced/#ssl-cert-verification

verify关键字是一个标志,不用于提供证书文件。您提供了非空字符串,该字符串解析为True布尔上下文。

使用cert=关键字提供证书文件的路径,或禁用verify=False.

编辑:虽然文档说您实际上可以将 CA 路径传递给verify=,但没有示例。查看您收到的整个回溯将会很有帮助。

  • 我不想完全禁用证书验证,只想禁用主机名检查。 (2认同)