2011-01-07 87 views
1

我正在嘗試訪問REST API。urllib2支持搶先認證認證嗎?

我可以讓它在Curl/REST Client(UI工具)中工作,並啓用搶先認證。

但是,使用urllib2,它似乎不支持默認情況下,我找不到方法來打開它。

謝謝:)

+0

向我們提供有關您需要什麼,您嘗試過什麼以及UI工具如何工作的更多詳細信息。 – TryPyPy 2011-01-17 01:25:02

回答

6

這是一個簡單的搶先式HTTP基本認證處理程序,基於urllib2.HTTPBasicAuthHandler的代碼。它可以以完全相同的方式使用,除了Authorization標頭將被添加到請求與一個匹配的URL。請注意,該處理程序應與HTTPPasswordMgrWithDefaultRealm一起使用。這是因爲你沒有領先優勢,所以在WWW-Authenticate挑戰中沒有領域迴歸。

class PreemptiveBasicAuthHandler(urllib2.BaseHandler): 

     def __init__(self, password_mgr=None): 
       if password_mgr is None: 
         password_mgr = urllib2.HTTPPasswordMgrWithDefaultRealm() 
       self.passwd = password_mgr 
       self.add_password = self.passwd.add_password 

     def http_request(self,req): 
       uri = req.get_full_url() 
       user, pw = self.passwd.find_user_password(None,uri) 
       #logging.debug('ADDING REQUEST HEADER for uri (%s): %s:%s',uri,user,pw) 
       if pw is None: return req 

       raw = "%s:%s" % (user, pw) 
       auth = 'Basic %s' % base64.b64encode(raw).strip() 
       req.add_unredirected_header('Authorization', auth) 
       return req 
+0

非常感謝。我非常感謝你花時間回答這個問題並給出一個很好的解釋。 – thinkanotherone 2011-12-20 22:51:29

0

取決於需要什麼樣的認證,您可以手動將它們添加到您的請求發送授權頭,你發出一個體前。

4

類似於@ thom-nichols的回答;但是子類HTTPBasicAuthHandler也處理HTTPS請求。

import urllib2 
import base64 

class PreemptiveBasicAuthHandler(urllib2.HTTPBasicAuthHandler): 
    '''Preemptive basic auth. 

    Instead of waiting for a 403 to then retry with the credentials, 
    send the credentials if the url is handled by the password manager. 
    Note: please use realm=None when calling add_password.''' 
    def http_request(self, req): 
     url = req.get_full_url() 
     realm = None 
     # this is very similar to the code from retry_http_basic_auth() 
     # but returns a request object. 
     user, pw = self.passwd.find_user_password(realm, url) 
     if pw: 
      raw = "%s:%s" % (user, pw) 
      auth = 'Basic %s' % base64.b64encode(raw).strip() 
      req.add_unredirected_header(self.auth_header, auth) 
     return req 

    https_request = http_request 

這裏是處理不給你401 HTTP錯誤(與權威性重試)一詹金斯服務器的例子。我使用urllib2.install_opener使事情變得簡單。

jenkins_url = "https://jenkins.example.com" 
username = "johndoe" 
api_token = "some-cryptic-value" 

auth_handler = PreemptiveBasicAuthHandler() 
auth_handler.add_password(
    realm=None, # default realm. 
    uri=jenkins_url, 
    user=username, 
    passwd=api_token) 
opener = urllib2.build_opener(auth_handler) 
urllib2.install_opener(opener)