2014-04-04 46 views
2

我試圖使用Python腳本訪問學術服務提供商(SP)託管的期刊文章。使用Python請求訪問Shibboleth身份驗證服務器的SSL錯誤

服務器使用Shibboleth登錄進行身份驗證。我讀Logging into SAML/Shibboleth authenticated server using python並嘗試使用Python請求實現登錄。

該腳本首先查詢SP以獲取通向我的IDP機構的鏈接,然後假定自動使用IDP進行身份驗證。第一部分工作正常,但是當連接到IDP時,它會發生SSL錯誤。 這是我用:

import requests 
import lxml.html 

LOGINLINK = 'https://www.jsave.org/action/showLogin?redirectUri=%2F' 
USERAGENT = 'Mozilla/5.0 (X11; Linux x86_64; rv:28.0) Gecko/20100101 Firefox/28.0' 

s = requests.session() 
s.headers.update({'User-Agent' : USERAGENT}) 

# getting the page where you can search for your IDP 
# need to get the cookies so we can continue 
response = s.get(LOGINLINK) 
rtext = response.text 
print('Don\'t see your school?' in rtext) # prints True 

# POSTing the name of my institution 
data = { 
    'institutionName' : 'tubingen', 
    'submitForm' : 'Search', 
    'currUrl' : '%2Faction%2FshowBasicSearch', 
    'redirectUri' : '%2F', 
    'activity' : 'isearch' 
} 
response = s.post(BASEURL + '/action/showLogin', data=data) 
rtext = response.text 
print('university of tubingen' in rtext) # prints True 

# get the link that leads to the IDP 
tree = lxml.html.fromstring(rtext) 
loginlinks = tree.cssselect('a.extLogin') 
if (loginlinks): 
    loginlink = loginlinks[0].get('href') 
else: 
    exit(1) 

print('continuing to IDP') 
response = s.get(loginlink) 
rtext = response.text 
print('zentrale Anmeldeseite' in rtext) 

這產生了:

continuing to IDP... 

2014-04-04 10:04:06,010 - INFO - Starting new HTTPS connection (1): idp.uni-tuebingen.de 
Traceback (most recent call last): 

File "/usr/lib/python3.4/site-packages/requests/packages/urllib3/connectionpool.py", line 480, in urlopen 
body=body, headers=headers) 

File "/usr/lib/python3.4/site-packages/requests/packages/urllib3/connectionpool.py", line 285, in _make_request 
conn.request(method, url, **httplib_request_kw) 

File "/usr/lib/python3.4/http/client.py", line 1066, in request 
self._send_request(method, url, body, headers) 

File "/usr/lib/python3.4/http/client.py", line 1104, in _send_request 
self.endheaders(body) 

File "/usr/lib/python3.4/http/client.py", line 1062, in endheaders 
self._send_output(message_body) 

File "/usr/lib/python3.4/http/client.py", line 907, in _send_output 
self.send(msg) 

File "/usr/lib/python3.4/http/client.py", line 842, in send 
self.connect() 

File "/usr/lib/python3.4/site-packages/requests/packages/urllib3/connection.py", line 164, in connect 
ssl_version=resolved_ssl_version) 

File "/usr/lib/python3.4/site-packages/requests/packages/urllib3/util.py", line 639, in ssl_wrap_socket 
return context.wrap_socket(sock, server_hostname=server_hostname) 

File "/usr/lib/python3.4/ssl.py", line 344, in wrap_socket 
_context=self) 

File "/usr/lib/python3.4/ssl.py", line 540, in __init__ 
self.do_handshake() 

File "/usr/lib/python3.4/ssl.py", line 767, in do_handshake 
self._sslobj.do_handshake() 

ssl.SSLError: [SSL: TLSV1_ALERT_INTERNAL_ERROR] tlsv1 alert internal error (_ssl.c:598) 


During handling of the above exception, another exception occurred: 

Traceback (most recent call last): 

File "/usr/lib/python3.4/site-packages/requests/adapters.py", line 330, in send 
timeout=timeout 

File "/usr/lib/python3.4/site-packages/requests/packages/urllib3/connectionpool.py", line 504, in urlopen 
raise SSLError(e) 

requests.packages.urllib3.exceptions.SSLError: [SSL: TLSV1_ALERT_INTERNAL_ERROR] tlsv1 alert internal error (_ssl.c:598) 


During handling of the above exception, another exception occurred: 

Traceback (most recent call last): 
File "./try.py", line 154, in <module> 
response = s.get(loginlink) 

File "/usr/lib/python3.4/site-packages/requests/sessions.py", line 395, in get 
return self.request('GET', url, **kwargs) 

File "/usr/lib/python3.4/site-packages/requests/sessions.py", line 383, in request 
resp = self.send(prep, **send_kwargs) 

File "/usr/lib/python3.4/site-packages/requests/sessions.py", line 486, in send 
r = adapter.send(request, **kwargs) 

File "/usr/lib/python3.4/site-packages/requests/adapters.py", line 385, in send 
raise SSLError(e) 

requests.exceptions.SSLError: [SSL: TLSV1_ALERT_INTERNAL_ERROR] tlsv1 alert internal error (_ssl.c:598) 

使用s.get(LOGINLINK,驗證= FALSE)產生完全相同的錯誤。簡單地使用urllib.request.urlopen(loginlink)也是如此。

另一方面,打印和粘貼到Firefox的鏈接,工作正常。

回答

1

使用openssl s_client嘗試後,它看起來像目標idp.uni-tuebingen.de:443只支持SSLv3並在任何新的行爲上行事不端。隨着強制的SSLv3得到:

$ openssl s_client -connect idp.uni-tuebingen.de:443 -ssl3 
CONNECTED(00000003) 
depth=3 C = DE, O = Deutsche Telekom AG, OU = T-TeleSec Trust Center, CN = Deutsche Telekom Root CA 2 
... 

但一個默認設置或者強迫TLv1(-tls1)它只返回一個警告:

openssl s_client -connect idp.uni-tuebingen.de:443 
CONNECTED(00000003) 
140493591938752:error:14077438:SSL routines:SSL23_GET_SERVER_HELLO:tlsv1 alert internal error:s23_clnt.c:741: 

所以,你需要找到一種方法來強制的SSLv3此連接。我現在還不熟悉Python,但可能http://docs.python-requests.org/en/latest/user/advanced/章節「示例:特定的SSL版本」有幫助。

爲什麼它可以與firefox協同工作:如果與安全版本的連接失敗,瀏覽器通常會嘗試降級SSL版本。例如。大家正在努力解決破碎的東西,使破碎的東西的主人無意修復它:(

+0

非常感謝你,我得到它的Python請求遵循你的意見和http:// lukasa。 co.uk/2013/01/Choosing_SSL_Version_In_Requests/。添加了一個強制「ssl_version = ssl.PROTOCOL_SSLv3」的適配器類。 – user3497169

相關問題