L'implementazione di un gestore di autenticazione Python personalizzati
Domanda
La risposta a un domanda precedente ha mostrato che Nexus implementare un autenticazione aiuto personalizzato chiamato "NxBASIC".
Come faccio a iniziare ad attuare un gestore in Python?
Aggiornamento:
L'implementazione del gestore per ogni suggerimento di Alex sembra essere l'approccio giusto, ma non riesce il tentativo di estrarre il sistema e regno dal authreq. Il valore restituito per authreq è:
str: NxBASIC realm="Sonatype Nexus Repository Manager API""
AbstractBasicAuthHandler.rx.search (authreq) è solo restituire un singolo tupla:
tuple: ('NxBASIC', '"', 'Sonatype Nexus Repository Manager API')
in modo schema, regno = mo.groups () fallisce. Dalla mia conoscenza limitata regex sembra che l'espressione regolare standard dal AbstractBasicAuthHandler deve corrispondere schema e regno, ma sembra di non farlo.
L'espressione regolare è:
rx = re.compile('(?:.*,)*[ \t]*([^ \t]+)[ \t]+'
'realm=(["\'])(.*?)\\2', re.I)
Aggiornamento 2: Da ispezione AbstractBasicAuthHandler, l'elaborazione standard è quello di fare:
scheme, quote, realm = mo.groups()
La modifica a questo funziona. Ora solo bisogno di impostare la password contro il regno corretta. Grazie Alex!
Soluzione
Se, come descritto, il nome e la descrizione sono le uniche differenze tra questo "NxBasic" e il buon vecchio "di base", allora si potrebbe in sostanza, copia-incolla-modifica del codice da urllib2.py (che purtroppo non esporre il regime nome facilmente superabile in sé), come segue (vedi urllib2.py 's fonti on-line):
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
Come si può vedere mediante ispezione, ho appena cambiato due stringhe da "base" per "NxBasic" (e gli equivalenti minuscole) da ciò che è in urrlib2.py (in astratto base superclasse gestore autenticazione della http autenticazione di base classe del gestore).
Provare a utilizzare questa versione - e se ancora non funziona, almeno averlo essere il codice può aiutarvi ad aggiungere stampa / dichiarazioni di registrazione, i punti di interruzione, ecc, per capire meglio cosa sta rompendo e come. Buona fortuna! (Mi dispiace non posso fare di più, ma non ho alcun Nexus intorno a sperimentare).