Използвам заявки за свързване към API на RESTful. Сървърът, до който бих искал да достигна, използва ssl със самостоятелно сертифициран сертификат.
cafile = "gateway.pem"
r = requests.get(request, auth=("admin", "password"), verify=cafile)
проблемът е, че получавам SSLError на име на хостнесъответствие. трябва да има начин да деактивирате проверката на името на хоста, без да деактивирате валидирането на сертификат, както в много реализации на Java, но не мога да намеря как да го направя с заявки в python.
stacktrace:
Traceback (most recent call last):
File "<pyshell#43>", line 1, in <module>
r = requests.get(request, auth=("admin", "password"), verify="gateway.pem")
File "C:Python27libsite-packagesrequests-2.0.0-py2.7.eggrequestsapi.py", line 55, in get
return request("get", url, **kwargs)
File "C:Python27libsite-packagesrequests-2.0.0-py2.7.eggrequestsapi.py", line 44, in request
return session.request(method=method, url=url, **kwargs)
File "C:Python27libsite-packagesrequests-2.0.0-py2.7.eggrequestssessions.py", line 357, in request
resp = self.send(prep, **send_kwargs)
File "C:Python27libsite-packagesrequests-2.0.0-py2.7.eggrequestssessions.py", line 460, in send
r = adapter.send(request, **kwargs)
File "C:Python27libsite-packagesrequests-2.0.0-py2.7.eggrequestsadapters.py", line 358, in send
raise SSLError(e)
SSLError: hostname "10.76.92.70" doesn"t match u"lital.com"
Как може да се направи това?
Отговори:
8 за отговор № 1Заявките не позволяват това директно, но можете да предоставите персонализиран транспортен адаптер, който използва функциите на основата 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)
Подробно assert_hostname
param работи както следва: ако None
използвайте името на хоста от URL адреса, ако False
потиснете проверката на името на хоста, ако потребителски низ се валидира спрямо този низ.
4 за отговор № 2
Малко закъснявам на партито, но 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"})
1 за отговор № 3
Погледнахте ли в SSLContext.check_hostname
параметър? Трябва да можете да го зададете на False и не трябва да проверява името на хоста:
context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
context.verify_mode = ssl.CERT_REQUIRED
context.check_hostname = True
context.load_default_certs()
Единственото ограничение е, че това работи само в Python 3.4 и по-нови версии.
справка: https://docs.python.org/3/library/ssl.html#ssl.SSLContext.check_hostname
-2 за отговор № 4
http://docs.python-requests.org/en/latest/user/advanced/#ssl-cert-verification
verify
ключовата дума е флаг, а не за предоставяне на certfile. Вие предоставихте там непроменлив низ, който се разрешава на True
в булев контекст.
употреба cert=
ключова дума, за да предоставите път към файлове със сертификати или да деактивирате потвърждаването с verify=False
.
РЕДАКТИРАНЕ: въпреки че документацията казва, че всъщност можете да преминете път на CA verify=
, но няма примери. Би било полезно да видите цели проследявания, които получавате.
-3 за отговор № 5
Ако това е само за тестване, тогава просто добавете запис в / etc / hosts към вашата локална система (при условие че имате достъп).