我正在编写一个简单的脚本,涉及CAS、jspring安全检查、重定向等。我想使用Kenneth Reitz的python请求,因为它是一个伟大的作品!然而,CAS需要通过SSL进行验证,所以我必须先通过这一步。我不知道Python请求想要什么?这个SSL证书应该驻留在哪里?
Traceback (most recent call last):
File "./test.py", line 24, in <module>
response = requests.get(url1, headers=headers)
File "build/bdist.linux-x86_64/egg/requests/api.py", line 52, in get
File "build/bdist.linux-x86_64/egg/requests/api.py", line 40, in request
File "build/bdist.linux-x86_64/egg/requests/sessions.py", line 209, in request
File "build/bdist.linux-x86_64/egg/requests/models.py", line 624, in send
File "build/bdist.linux-x86_64/egg/requests/models.py", line 300, in _build_response
File "build/bdist.linux-x86_64/egg/requests/models.py", line 611, in send
requests.exceptions.SSLError: [Errno 1] _ssl.c:503: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
有些服务器没有Letsencrypt的可信根证书。
例如,假设下面的url指向的服务器受到Letsencrypt SSL的保护。
requests.post(url, json=data)
此请求可能使用[SSL: CERTIFICATE_VERIFY_FAILED]失败,因为请求服务器没有Letsencrypt的根证书。
当发生这种情况时,请从下面的链接下载活动自签名的“pem”证书。
https://letsencrypt.org/certificates/。(在撰写本文时,ISRG根X1处于活动状态)
现在,在verify参数中使用它,如下所示。
requests.post(url, json=data, verify='path-to/isrgrootx1.pem')
这与@rafael-almeida的回答类似,但我想指出的是,对于2.11+的请求,没有3个值可以验证,实际上有4个:
True:根据请求的内部可信ca进行验证。
False:完全跳过证书验证。(不推荐)
CA_BUNDLE文件的路径。请求将使用它来验证服务器的证书。
包含公共证书文件的路径。请求将使用它来验证服务器的证书。
我剩下的答案是关于#4,如何使用包含证书的目录来验证:
获取所需的公共证书,并将它们放在一个目录中。
严格地说,您可能“应该”使用带外方法获取证书,但您也可以使用任何浏览器下载它们。
如果服务器使用证书链,请确保获取链中的每个证书。
根据请求文档,包含证书的目录必须首先使用“rehash”实用程序(openssl rehash)进行处理。
(这需要openssl 1.1.1+,并且不是所有的Windows openssl实现都支持rehash。如果openssl rehash对你不起作用,你可以尝试在https://github.com/ruby/openssl/blob/master/sample/c_rehash.rb上运行rehash ruby脚本,尽管我还没有尝试过。)
我在让请求识别我的证书时遇到了一些麻烦,但是在我使用openssl x509 -outform PEM命令将证书转换为Base64 . PEM格式后,一切都完美地工作了。
你也可以只做惰性重哈希:
try:
# As long as the certificates in the certs directory are in the OS's certificate store, `verify=True` is fine.
return requests.get(url, auth=auth, verify=True)
except requests.exceptions.SSLError:
subprocess.run(f"openssl rehash -compat -v my_certs_dir", shell=True, check=True)
return requests.get(url, auth=auth, verify="my_certs_dir")