Python - проблема SSL с Oauth2

Кажется, у меня возникают проблемы с SSL всякий раз, когда я пытаюсь использовать oAuth2 в Python. Я провел большую часть дня, пытаясь отладить его, но, похоже, не могу понять это.

Вот мой Python Script (красивый и простой):

import oauth2.oauth2 as oauth
import urlparse
import time

## If you're actually processing requests, you'll want this
# import simplejson


### GET A REQUEST TOKEN ###

consumer = oauth.Consumer(key="***KEYHERE***", secret="***KEYSECRETHERE***")

request_token_url = 'https://api.instagram.com/oauth/access_token'

client = oauth.Client(consumer)
resp, content = client.request(request_token_url, "GET")

request_token = dict(urlparse.parse_qsl(content))


token = oauth.Token(request_token['oauth_token'], request_token['oauth_token_secret'])

И эти ошибки от интерпретатора Python:

Traceback (most recent call last):
  File "E:\Projects\oAuth2Test\test.py", line 16, in <module>
    resp, content = client.request(request_token_url, "GET")
  File "E:\Projects\oAuth2Test\oauth2\oauth2.py", line 682, in request
    connection_type=connection_type)
  File "E:\Projects\oAuth2Test\httplib2\httplib2.py", line 1445, in request
    (response, content) = self._request(conn, authority, uri, request_uri, method, body, headers, redirections, cachekey)
  File "E:\Projects\oAuth2Test\httplib2\httplib2.py", line 1197, in _request
    (response, content) = self._conn_request(conn, request_uri, method, body, headers)
  File "E:\Projects\oAuth2Test\httplib2\httplib2.py", line 1133, in _conn_request
    conn.connect()
  File "E:\Projects\oAuth2Test\httplib2\httplib2.py", line 914, in connect
    raise SSLHandshakeError(e)
SSLHandshakeError: [Errno 1] _ssl.c:503: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed

Теперь, чтобы было известно, у меня есть файл cacerts.txt, который поставляется с httplib2 в нужном месте, и он найден, но у меня все еще есть эта проблема. Любая помощь приветствуется, спасибо!

6 ответов

Решение

cacerts.txt содержит слишком мало CA. Если вы замените его на cacert.pem, то ошибки ssl не будет. Вот тестовый скрипт:

#!/usr/bin/env python3
import http.client
import ssl

####context = ssl.create_default_context(cafile='cacerts.txt') # ssl.SSLError
####context = ssl.create_default_context(cafile='cacert.pem')  # works   
context = ssl.create_default_context()  # works as is on the recent versions
#NOTE: ssl.CERT_REQUIRED is set for the default Purpose.SERVER_AUTH

h = http.client.HTTPSConnection('api.instagram.com', 443, context=context)
h.request('POST', '/oauth/access_token')
resp = h.getresponse()
print(resp.status, resp.reason) # produce expected 400 http error
print(resp.headers)
print(resp.read())

Как показано в примере, список CA по умолчанию может быть достаточно для последних версий программного обеспечения.

Первый забег pip install certifi, Затем установите клиентское свойство ca_certs, прежде чем делать какие-либо запросы:

client = oauth.Client(consumer)
client.ca_certs = certifi.where()

Это было вдохновлено предложением Jterrace использовать httplib2.Http.add_certificate

Я столкнулся с той же проблемой, связанной с OAuth-звонком Flask-Social в Facebook. Самое простое решение - установить плагин httplib2.ca_certs_locator.

В httplib2.init.py, есть встроенная проверка для загрузки сертификатов из другого источника вместо файла cacerts.txt, поставляемого с библиотекой:

try:
    # Users can optionally provide a module that tells us where the CA_CERTS
    # are located.
    import ca_certs_locater
    CA_CERTS = ca_certs_locater.get()
except ImportError:
    # Default CA certificates file bundled with httplib2.
    CA_CERTS = os.path.join(
        os.path.dirname(os.path.abspath(__file__ )), "cacerts.txt")

Установка этого плагина устранила проблему для меня без каких-либо изменений кода / взлома.

Файл cacerts.txt по умолчанию, поставляемый с httplib2, содержит следующие сертификаты:

  • Verisign / RSA Secure Server CA
  • Thawte Personal Basic CA
  • Thawte Personal Premium CA
  • Thawte Personal Freemail CA
  • Thawte Server CA
  • Thawte Premium Server CA
  • Equifax Secure CA
  • Государственный первичный центр сертификации Verisign Class 1
  • Государственный первичный центр сертификации Verisign Class 2
  • Государственный первичный центр сертификации Verisign класса 3
  • Государственный первичный центр сертификации Verisign Class 1 - G2
  • Государственный первичный центр сертификации Verisign Class 2 - G2
  • Государственный первичный центр сертификации Verisign класса 3 - G2
  • Государственный первичный центр сертификации Verisign Class 4 - G2
  • Государственный первичный центр сертификации Verisign Class 1 - G3
  • Государственный первичный центр сертификации Verisign Class 2 - G3
  • Государственный первичный центр сертификации Verisign класса 3 - G3
  • Государственный первичный центр сертификации Verisign Class 4 - G3
  • Equifax Secure Global eBusiness CA
  • Equifax Secure eBusiness CA 1
  • Equifax Secure eBusiness CA 2
  • Thawte Time Stamping CA
  • thawte первичный корень CA
  • Государственный первичный центр сертификации VeriSign класса 3 - G5
  • Entrust.net безопасный центр сертификации серверов
  • Пакет корневых сертификатов Go Daddy Certification Authority

HTTPS сертификат instagram подписывается:

  • GeoTrust Global CA

Вам нужно будет добавить сертификат в ваш cacerts.txt

Еще один способ обновить свой cacerts.txt файл хранить httplib2 до настоящего времени. Они иногда обновляют этот файл, поэтому, если вы столкнулись с этой проблемой, проверьте, не используете ли вы последнюю версию библиотеки, и обновите ее.

У меня была такая же ошибка в моей системе (OSX Yosemite), на которой была установлена ​​старая версия Python 2.7 (2.7.1).

Я обновил Python до 2.7.10, что решило проблему.

https://www.python.org/downloads/release/python-2710/

Подсказка была в следующем предупреждающем сообщении, которое я увидел, когда экспериментировал с различными решениями:

"InsecurePlatformWarning: настоящий объект SSLContext недоступен. Это препятствует правильной настройке SSL urllib3 и может привести к сбою некоторых SSL-соединений. Для получения дополнительной информации см. https://urllib3.readthedocs.org/en/latest/security.html

Другие вопросы по тегам