Implement a custom Python authentication handler

The answer to the previous question showed that Nexus implements a custom authentication called "NxBASIC".

How do I start implementing a handler in python?


Update:

The implementation of the handler suggested by Alex looks right, but does not try to extract the schema and region from authreq. Return value for authreq:

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

AbstractBasicAuthHandler.rx.search (authreq) returns only one tuple:

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

therefore, the scheme, realm = mo.groups () fails. From my limited knowledge of regular expressions, it seems that the standard regular expression from AbstractBasicAuthHandler should match the pattern and scope, but it doesn't seem to be that way.

Regular expression:

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

2: AbstractBasicAuthHandler :

scheme, quote, realm = mo.groups()

. . , !

+3
1

, , "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

, "Basic" "NxBasic" ( ) , urrlib2.py( auth- http basic auth ).

- , , , /, .., , . ! (, , Nexus ).

+1

Source: https://habr.com/ru/post/1711833/


All Articles