【问题标题】:does urllib2 support preemptive authentication authentication?urllib2 支持抢占式身份验证吗?
【发布时间】:2011-01-07 17:52:19
【问题描述】:

我正在尝试访问 REST API。

我可以让它在 Curl/REST Client(UI 工具)中工作,并启用抢先身份验证。

但是,使用 urllib2,它似乎默认不支持这个,我找不到打开它的方法。

谢谢:)

【问题讨论】:

  • 向我们提供有关您需要什么、您尝试过什么以及 UI 工具如何工作的更多详细信息。

标签: python http urllib2


【解决方案1】:

这是一个基于urllib2.HTTPBasicAuthHandler 的代码的简单的抢先式 HTTP 基本身份验证处理程序。它可以以完全相同的方式使用,除了 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

【讨论】:

  • 非常感谢。非常感谢您花时间用一个很好的解释来回答这个问题。
【解决方案2】:

类似于@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

这是一个处理 jenkins 服务器的示例,它不会向您发送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)

【讨论】:

    【解决方案3】:

    根据需要哪种身份验证,您可以手动发送授权标头,方法是在发送正文之前将它们添加到您的请求中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-12
      • 1970-01-01
      • 2018-12-15
      • 1970-01-01
      相关资源
      最近更新 更多