2011-01-07 75 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)