2015-03-13 1 views
3

Lorsque j'essaie d'accéder à un itinéraire avec le décorateur @auth.login_required, une fenêtre me demande d'entrer mon nom d'utilisateur et mon mot de passe. Après avoir saisi cette information, les paramètres username_or_token et password pour la fonction verify_password sont ''. Pourquoi les données sont-elles vides?Flask-HTTPAuth verify_password Fonction ne recevant pas le nom d'utilisateur ou le mot de passe

@auth.verify_password 
def verify_password(username_or_token, password): 
    # first try to authenticate by token 
    user = USER.verify_auth_token(username_or_token) 
    logger.debug("user = %r", user) 
    logger.debug("Entered USEREMAIL = %r" , username_or_token) 
    logger.debug("entered password = %r" , password) 

    if not user: 
     # try to authenticate with username/password 
     user = session.query(USER).filter_by(USEREMAIL=username_or_token).first() 
     if not user or not user.verify_password(password): 
      return False 
    g.user = user 
    return True 

MISE À JOUR

J'ai simplifié le code à ceci:

@auth.verify_password 
def verify_password(username, password): 
    logger.debug("username = %s" % username) 
    logger.debug("password = %s" % password) 
    return true 


@app.route('/api/token') 
@auth.login_required 
def get_auth_token(): 
    return "Hello, %s!" % auth.username() 

Je teste cette fonction en utilisant Advanced Rest Client.

http://localhost:8081/myapp/api/token

J'ai aussi attaché un en-tête Authorization.

User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.89 Safari/537.36 
Authorization: Basic YXNkOmFzZA== 
Accept: */* 
Accept-Encoding: gzip, deflate, sdch 
Accept-Language: en-US,en;q=0.8,zh-CN;q=0.6,zh-TW;q=0.4 

Il en résulte la sortie:

Hello, !

fichier journal:

username = 
password = 

Je suis également jamais invité à entrer dans mon security credentials plus.

Une autre chose étrange est que même si je change le retour à false dans verify_password, je reçois toujours la même sortie: Hello, !

+0

Il serait utile de fournir un exemple complet reproduisant le problème. Le nom d'utilisateur et le mot de passe sont définis comme des chaînes vides uniquement lorsque le client n'envoie pas l'en-tête 'Authorization', ce qui peut être un problème côté client. – Miguel

Répondre

3

j'ai vécu similaire à OP.. Si vous utilisez mod_wsgi, assurez-vous de définir WSGIPassAuthorization On comme documented here.

1

Je suis en mesure d'obtenir le nom d'utilisateur et mot de passe avec cet exemple minimal:

from flask import Flask 
from flask.ext.httpauth import HTTPBasicAuth 

app = Flask(__name__) 
auth = HTTPBasicAuth() 

@auth.verify_password 
def foo(username, password): 
    print "verifying...." 
    print username 
    print password 
    return False 

@app.route('/') 
@auth.login_required 
def index(): 
    return "Hello, %s!" % auth.username() 

if __name__ == '__main__': 
    app.run() 

Cependant, tout en travaillant dessus, chrome a enregistré les cookies et j'ai dû supprimer tout le cache, y compris les cookies, parce que je devenais automatiquement authentifié. Peut-être que cela pourrait vous causer des problèmes.

Aussi, n'oubliez pas de marquer @app.route("/") avec @auth.login_required décorateur. Sinon, le rappel verify_password n'est pas appelé.

0

Le rappel @verify_password doit renvoyer True si vous autorisez l'utilisateur ou False si ce n'est pas le cas. Dans cette fonction, un utilisateur anonyme (c'est-à-dire un utilisateur qui n'envoie pas d'authentification) est représenté avec des chaînes vides pour les champs username et password.

Dans votre code, vous ne vérifiez pas que les informations d'identification de l'utilisateur sont valides. Au lieu de cela, essayer quelque chose comme ceci:

@auth.verify_password 
def verify_password(username, password): 
    logger.debug("username = %s" % username) 
    logger.debug("password = %s" % password) 
    if username == '': 
     return False 
    return true 

La volonté ci-dessus permettent une combinaison de nom d'utilisateur/mot de passe, mais ne laissera pas les utilisateurs anonymes

+0

Merci @Miguel. L'utilisation de cette fonction permet d'arrêter les utilisateurs anonymes. Cependant, j'ai toujours le même problème avec le «nom d'utilisateur» étant «». Voici comment j'envoie ma requête (besoin de Chrome Advanced Rest Client): 'chrome-extension: //hgmloofddffdnphfgcellkdfbfbjeloo/RestClient.html#RequestPlace: default'. Quand j'envoie ceci, je suis invité avec un écran d'autorisation. Peu importe ce que je tape ici, puis cliquez sur «Connexion», la boîte réapparaît constamment. Lorsque j'appuie finalement sur 'Cancel', j'obtiens le message' Unauthorized Access'. –

+0

@Giri: c'est un comportement du navigateur, chaque fois que le serveur répond avec un code d'état 401, le navigateur affiche la boîte de dialogue de connexion. Un moyen facile d'éviter cela est de renvoyer un code d'état 403 au lieu de 401. Vous pouvez le faire dans votre gestionnaire d'erreur Flask-HTTPAuth. – Miguel

1

J'ai eu le même problème lors de l'exécution de mon application Flask sur EC2. Donc je suppose que vous utilisez votre application derrière un service wsgi. Le fait est que wsgi interceptera chaque en-tête de requête à des fins différentes, nous devons donc faire quelques configurations pour nous assurer que l'en-tête d'authentification sera intact jusqu'à ce qu'il atteigne notre application. Merci pour la réponse d'Erik Stephens m'a aidé à résoudre ce problème. Je mets WSGIPassAuthorization sur /etc/httpd/conf.d/wsgi.conf sur mon instance EC2 et redémarre le service httpd. Vous voudrez peut-être avoir cette mise à jour pour seulement votre fichier de configuration wsgi de l'application jusqu'à votre configuration. Espérons que cela aidera quelqu'un avec le même problème lors du lancement de l'application à aws.