2012-02-14 41 views
13

每當嘗試在Python中使用oAuth2時,我似乎都遇到了SSL問題。我在下午的大部分時間都試圖調試它,但似乎無法弄清楚。Python - Oauth2的SSL問題

這裏是我的Python腳本(尼斯和簡單):

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一起發現,但我仍然有這個問題。任何幫助表示讚賞,謝謝!

回答

8

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列表可能已足夠。

+0

這個'cacerts.pem'似乎更加完整。方便的鏈接。 – 2012-05-09 10:23:07

+1

作爲一個快速入侵,你也可以用cacerts覆蓋cacerts.txt。以上 - 缺點是你需要確保在你的所有virtualenv中都做到這一點 - 所以它不是很理想。 – Damian 2013-02-03 22:09:07

2

附帶httplib2的默認cacerts.txt包含這些證書:

  • 威瑞/ RSA安全服務器CA
  • Thawte的個人基本CA
  • Thawte的個人保費CA
  • Thawte的個人免費信箱CA
  • Thawte服務器CA
  • Thawte高級服務器CA
  • Equifax安全CA
  • 威瑞類1根公用主證書頒發機構
  • 威瑞2級公用主證書頒發機構
  • 威瑞類3公用主證書頒發機構
  • 威瑞類1個公用主證書頒發機構 - G2
  • Verisign第2類公共主要認證機構 - G2
  • Verisign第3類公共主要認證機構 - G2
  • Veri符號4類公用主證書頒發機構 - G2
  • 威瑞類1個公用主證書頒發機構 - G3
  • 威瑞類2公用主證書頒發機構 - G3
  • 威瑞3級公用主證書頒發機構 - G3
  • 威瑞類4公用主證書頒發機構 - G3
  • Equifax安全全球電子商務CA
  • Equifax安全的電子商務CA 1級
  • Equifax安全的電子商務CA 2
  • Thawte的時間戳CA
  • Thawte的主要根CA
  • 威瑞信3級公用主證書頒發機構 - G5
  • 委託。網絡安全服務器證書頒發機構
  • 的Go Daddy證書頒發機構的根證書捆綁

的Instagram的HTTPS證書是由簽署:

  • GeoTrust的全球CA

您將需要添加證書到您的cacerts.txt

+0

我找到了證書詳細信息,但是如何獲取oauth2來讀取不同的cacerts.txt? – Steve 2012-03-26 14:38:23

+0

oauth2'''Client''繼承自''httplib2.Http'',所以你應該調用它的[add_certificate](http://httplib2.googlecode.com/hg/doc/html/libhttplib2.html#httplib2。 Http.add_certificate)方法。 – jterrace 2012-03-26 15:03:38

7

首先,運行pip install certifi。然後設置客戶端的ca_certs性質,使得任何請求之前:

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

這是由jterrace的建議啓發,使用httplib2.Http.add_certificate

2

我當時正在與燒瓶社會的OAuth呼籲Facebook的同樣的問題。最簡單的解決方案是安裝httplib2.ca_certs_locator插件。

在httplib2中。 初始化的.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") 

在插件解決了這個問題,沒有安裝這對我來說代碼更改/劈一個回合。

+0

請注意,早期版本的httplib2不會嘗試從'ca_certs_locator'加載 – 2014-09-17 16:42:06

0

我在我的系統(OSX Yosemite)上安裝了舊版本的Python 2.7(2.7.1)時出現同樣的錯誤。

我將Python升級到了2.7.10,解決了這個問題。

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

線索是當我在不同的解決方案進行試驗,我看到了以下警告消息:

「InsecurePlatformWarning:一個真正的SSLContext對象不可用這可以防止urllib3從適當配置SSL。並且可能導致某些SSL連接失敗。有關更多信息,請參閱https://urllib3.readthedocs.org/en/latest/security.html#insecureplatformwarning

0

更新cacerts.txt文件的另一種方法是保持爲最新。他們偶爾會更新此文件,因此如果遇到此問題,請檢查您是否未使用該庫的最新版本並進行更新。