实现自定义 Python 身份验证处理程序

发布于 2024-07-26 06:52:48 字数 1154 浏览 2 评论 0 原文

上一个问题的答案表明 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')

因此 schema,realm = mo.groups() 失败。 从我有限的正则表达式知识看来,AbstractBasicAuthHandler 中的标准正则表达式应该匹配方案和领域,但似乎并非如此。

正则表达式是:

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

更新2: 从 AbstractBasicAuthHandler 的检查来看,默认处理是:

scheme, quote, realm = mo.groups()

更改为此工作。 我现在只需要针对正确的领域设置密码。 谢谢亚历克斯!

The answer to a previous question showed that Nexus implement a custom authentication helper called "NxBASIC".

How do I begin to implement a handler in python?


Update:

Implementing the handler per Alex's suggestion looks to be the right approach, but fails trying to extract the scheme and realm from the authreq.
The returned value for authreq is:

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

AbstractBasicAuthHandler.rx.search(authreq) is only returning a single tuple:

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

so scheme,realm = mo.groups() fails. From my limited regex knowledge it looks like the standard regex from AbstractBasicAuthHandler should match scheme and realm, but it seems not to.

The regex is:

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

Update 2:
From inspection of AbstractBasicAuthHandler, the default processing is to do:

scheme, quote, realm = mo.groups()

Changing to this works. I now just need to set the password against the correct realm. Thanks Alex!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

蛮可爱 2024-08-02 06:52:48

如果,如上所述,名称和描述是这个“NxBasic”和旧的“Basic”之间的唯一区别,那么您基本上可以从 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

正如您通过检查看到的,我刚刚将 urrlib2.py 中的两个字符串从“Basic”更改为“NxBasic”(以及小写等效项)(在 http basic auth handler 类的抽象 basic auth handler 超类中)。

尝试使用这个版本——如果它仍然不起作用,至少让它成为你的代码可以帮助你添加打印/日志语句、断点等,以更好地理解什么是破坏的以及如何破坏的。 祝你好运! (抱歉,我无法提供更多帮助,但我没有任何 Nexus 可供实验)。

If, as described, name and description are the only differences between this "NxBasic" and good old "Basic", then you could essentially copy-paste-edit some code from urllib2.py (which unfortunately doesn't expose the scheme name as easily overridable in itself), as follows (see urllib2.py's online sources):

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

As you can see by inspection, I've just changed two strings from "Basic" to "NxBasic" (and the lowercase equivalents) from what's in urrlib2.py (in the abstract basic auth handler superclass of the http basic auth handler class).

Try using this version -- and if it's still not working, at least having it be your code can help you add print/logging statements, breakpoints, etc, to better understand what's breaking and how. Best of luck! (Sorry I can't help further but I don't have any Nexus around to experiment with).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文