实现自定义Python认证处理器

3 投票
1 回答
1500 浏览
提问于 2025-04-15 12:40

之前一个问题的回答提到,Nexus实现了一个叫做 "NxBASIC" 的自定义认证助手。

我该如何开始在Python中实现一个处理器呢?


更新:

按照Alex的建议来实现这个处理器看起来是个不错的方向,但在尝试从authreq中提取方案和领域时失败了。authreq返回的值是:

str: NxBASIC realm="Sonatype Nexus Repository Manager API""

AbstractBasicAuthHandler.rx.search(authreq) 只返回了一个元组:

tuple: ('NxBASIC', '"', 'Sonatype Nexus Repository Manager API')

所以 scheme, realm = mo.groups() 这一步就失败了。从我有限的正则表达式知识来看,AbstractBasicAuthHandler中的标准正则表达式应该能匹配到方案和领域,但似乎没有。

这个正则表达式是:

rx = re.compile('(?:.*,)*[ \t]*([^ \t]+)[ \t]+'
                'realm=(["\'])(.*?)\\2', re.I)

更新2:

通过检查AbstractBasicAuthHandler,默认的处理方式是:

scheme, quote, realm = mo.groups()

改成这个就可以了。我现在只需要把密码设置到正确的领域上。谢谢你,Alex!

1 个回答

1

如果像上面说的那样,"NxBasic"和老旧的"Basic"之间唯一的区别就是名字和描述,那么你其实可以从urllib2.py里复制一些代码,然后稍微修改一下。可惜的是,urllib2.py并没有很方便地让你直接修改方案名称。你可以参考这个链接查看urllib2.py的源代码:urllib2.py

import urllib2

class HTTPNxBasicAuthHandler(urllib2.HTTPBasicAuthHandler):

    def http_error_auth_reqed(self, authreq, host, req, headers):
        # host may be an authority (without userinfo) or a URL with an
        # authority
        # XXX could be multiple headers
        authreq = headers.get(authreq, None)
        if authreq:
            mo = AbstractBasicAuthHandler.rx.search(authreq)
            if mo:
                scheme, realm = mo.groups()
                if scheme.lower() == 'nxbasic':
                    return self.retry_http_basic_auth(host, req, realm)

    def retry_http_basic_auth(self, host, req, realm):
        user, pw = self.passwd.find_user_password(realm, host)
        if pw is not None:
            raw = "%s:%s" % (user, pw)
            auth = 'NxBasic %s' % base64.b64encode(raw).strip()
            if req.headers.get(self.auth_header, None) == auth:
                return None
            req.add_header(self.auth_header, auth)
            return self.parent.open(req)
        else:
            return None

从代码中你可以看到,我只是把"Basic"和它的小写形式改成了" NxBasic"。这个修改是在http基本认证处理类的抽象基本认证处理类里进行的。

试试这个版本吧——如果还是不行,至少你可以用自己的代码来添加一些打印信息或日志,设置断点等等,这样能更好地理解哪里出问题了,以及是怎么出问题的。祝你好运!(抱歉我不能提供更多帮助,因为我手边没有Nexus可以实验)。

撰写回答