2012-02-14 14 views
13

Wygląda na to, że mam problem z SSL przy próbie użycia oAuth2 w Pythonie. Spędziłem większość popołudnia na próbie debugowania, ale nie mogę tego zrozumieć.Python - Problem z SSL z Oauth2

Oto mój skrypt Pythona (Nice and simple):

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']) 

A to błąd z interpreter Pythona:

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 

Teraz tak to wiadomo, mam cacerts.txt że przyszedł z httplib2 we właściwym miejscu i został znaleziony, ale wciąż mam ten problem. Jakakolwiek pomoc się przyda, dzięki!

Odpowiedz

8

cacerts.txt zawiera za mało CAs. Jeśli zastąpisz go cacert.pem, to nie ma błędu ssl. Oto skrypt testowy:

#!/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()) 

Jak pokazuje przykład, domyślna lista CA może wystarczyć w przypadku najnowszych wersji oprogramowania.

+0

To 'cacerts.pem' wydaje się być bardziej kompletne. Poręczny link. –

+1

Jako szybki hack możesz również nadpisać cacerts.txt przy pomocy cacerts.pem powyżej - wadą jest to, że musisz upewnić się, że odbywa się to we wszystkich twoich virtualenv - więc nie jest to naprawdę idealne. – Damian

2

Domyślna cacerts.txt że pochodzi z httplib2 zawiera następujące certyfikaty:

  • Verisign/RSA Bezpieczny serwer CA
  • Thawte Prywatne Podstawowe CA
  • Thawte Osobiste Premium CA
  • Thawte Prywatne freemail CA
  • Serwer Thawte CA
  • Serwer Thawte Premium CA
  • Equifax Bezpieczne CA
  • Verisign Class Urząd 1 Primary Certification Public
  • Verisign Class Authority 2 Primary Certification Public
  • Verisign Class Organ 3 Public Primary Certification
  • Verisign Class 1 Primary organ publiczny Certification - G2
  • Główny publiczny organ certyfikacji firmy Verisign Class 2 - G2
  • Główny publiczny organ certyfikacji Verisign Class 3 - G2
  • Veri Znak Klasa 4 Podstawowa organ publiczny Certification - G2
  • Verisign Class 1 Primary Certification Authority publiczny - G3
  • Verisign Class 2 Podstawowa organ publiczny Certification - G3
  • Verisign Class 3 Podstawowa organ publiczny Certification - G3
  • Verisign Class 4 Primary Certification Authority publiczny - G3
  • Equifax Bezpieczne Globalny eBusiness CA
  • Equifax Bezpieczne eBusiness CA 1
  • Equifax Bezpieczne eBusiness CA 2
  • Thawte Czas stemplowanie CA
  • Thawte Podstawowa głównej CA
  • VeriSign Class 3 Primary Certification Authority publiczny - G5
  • Powierzać.Bezpieczne Certification Server netto Urząd
  • Go Daddy Certyfikat Certificate Authority głównej Bundle certyfikat HTTPS

Instagram jest podpisany przez:

  • GeoTrust Globalna CA

Trzeba będzie dodać certyfikat do pliku cacerts.txt

+0

Znalazłem szczegóły certyfikatu, ale jak mogę uzyskać oauth2, aby przeczytać inny plik cacerts.txt? – Steve

+0

Obiekt oauth2 '' Klient'' dziedziczy po '' httplib2.Http'', więc powinieneś wywołać jego [add_certificate] (http://httplib2.googlecode.com/hg/doc/html/libhttplib2.html#httplib2. Http.add_certificate). – jterrace

7

Najpierw uruchom pip install certifi. Następnie ustaw właściwość ca_certs klienta, przed podjęciem jakichkolwiek żądań:

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

ten został zainspirowany sugestią jterrace do korzystania httplib2.Http.add_certificate

2

biegałam do tego samego problemu z połączenia OAuth kolby-socjalnych do Facebook. Najprostszym rozwiązaniem jest zainstalowanie wtyczki httplib2.ca_certs_locator.

W httplib2. init, .py, jest sprawdzenie wbudowanej dla certyfikatów załadowczych z innego źródła zamiast pliku cacerts.txt wyposażonej biblioteki:

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") 

instalowania tej wtyczki w rozwiązaniu problemu dla mnie nie zmiany kodu/hack-a-rounds.

+0

Należy zauważyć, że wcześniejsze wersje protokołu httplib2 nie próbują ładować z 'ca_certs_locator' –

0

Miałem ten sam błąd w moim systemie (OS X Yosemite), który miał starą wersję zainstalowanego Pythona 2.7 (2.7.1).

Uaktualniłem Python do wersji 2.7.10, co rozwiązało problem.

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

Kluczem było w następującym komunikatem ostrzegawczym, które widziałem, kiedy byłem eksperymentować z różnymi rozwiązaniami:

„InsecurePlatformWarning: Prawdziwy obiekt SSLContext nie jest dostępny Zapobiega urllib3 od konfiguracji SSL odpowiednio. i może spowodować awarię niektórych połączeń SSL. Aby uzyskać więcej informacji, zobacz: https://urllib3.readthedocs.org/en/latest/security.html#insecureplatformwarning "

0

Jednym ze sposobów na zaktualizowanie pliku cacerts.txt jest aktualizowanie . Czasami aktualizują ten plik, więc jeśli napotkasz ten problem, sprawdź, czy nie używasz najnowszej wersji biblioteki i nie aktualizuj jej.