web-dev-qa-db-fra.com

Puis-je utiliser l'authentification HTTP de base avec Django?

Nous avons un site Web fonctionnant sur Apache, dont l'accès a un certain nombre de pages statiques protégées via l'authentification HTTP Basic.

J'ai écrit une nouvelle partie du site avec Django en utilisant le support intégré de Django pour la gestion des utilisateurs.

Le problème que j'ai est que les utilisateurs doivent se connecter une fois via l'authentification HTTP Basic, puis à nouveau en utilisant un formulaire de connexion Django. Cela est à la fois maladroit et très déroutant pour les utilisateurs.

Je me demandais si quelqu'un avait trouvé un moyen de faire Django connecter un utilisateur en utilisant les informations d'authentification HTTP Basic.

Je ne m'attends pas à transmettre un mot de passe à Django, mais plutôt si un utilisateur dave a été authentifié par Apache, il doit alors être automatiquement connecté à Django comme dave aussi.

(Une option serait de faire en sorte qu'Apache et Django partagent un magasin d'utilisateurs pour garantir les noms d'utilisateur et les mots de passe communs, mais cela impliquerait toujours deux invites de connexion, ce que j'essaie d'éviter.)

38
Dave Webb

Ceci a été ajouté à la version Django 1.3. Voir la documentation la plus récente à ce sujet ici: http://docs.djangoproject.com/en/dev/howto/auth-remote -user /

24
Traveler

Pour simplement prendre en charge l'authentification de base sur certaines demandes (et non le nettoyage avec le serveur Web - c'est ainsi que quelqu'un pourrait interpréter le titre de votre question), vous voudrez regarder ici:

http://www.djangosnippets.org/snippets/243/

34
wsorenson

Consultez les liens d'Oli. Vous voyez essentiellement le nom d'utilisateur authentifié comme vérifié par l'authentification HTTP de base dans Django en regardant request.META ['REMOTE_USER'].

Mise à jour: Test du correctif proposé pour le ticket # 689 , qui est disponible à jour dans le référentiel git de telenieko - ici . Il s'applique proprement au moins à la révision 9084 de Django.

Activez le backend d'authentification de l'utilisateur distant par

  • ajout de RemoteUserAuthMiddleware après AuthenticationMiddleware
  • ajout du paramètre AUTHENTICATION_BACKENDS = ('Django.contrib.auth.backends.RemoteUserAuthBackend',)

Si vous utilisez lighttpd et FastCGI comme je le fais, activez mod_auth, créez des informations d'identification pour un utilisateur de test (je l'ai appelé testuser et défini 123 comme mot de passe) et configurez le site Django pour exiger une authentification de base.

Le suivant urls.py peut être utilisé pour tester la configuration:

from Django.conf.urls.defaults import *
from Django.http import HttpResponse
from Django.contrib.auth.models import User
urlpatterns = patterns('',
    url(regex='^$',
        view=lambda request: HttpResponse(repr(request), 'text/plain')),

    url(regex='^user/$',
        view=lambda request: HttpResponse(repr(request.user), 'text/plain')),

    url(regex='^users/$',
        view=lambda request: HttpResponse(
            ','.join(u.username for u in User.objects.all()),
            'text/plain')),
)

Après avoir rechargé lighty et le serveur Django FCGI, le chargement de la racine du site demande maintenant l'authentification et accepte les informations d'identification testuser, puis génère un vidage de l'objet de demande. request.META ces nouvelles propriétés doivent être présentes:

'AUTH_TYPE': 'Basic'
'HTTP_AUTHORIZATION': 'Basic dGVzdHVzZXI6MTIz'
'REMOTE_USER': 'testuser'

Le /user/ L'URL peut être utilisée pour vérifier que vous êtes bien connecté en tant que testuser:

<User: testuser>

Et le /users/ L'URL répertorie désormais les testuser ajoutés automatiquement (ici l'utilisateur admin que j'avais créé lors de la réalisation de syncdb est également affiché):

admin,testuser

Si vous ne voulez pas patcher Django, il est trivial de détacher les classes RemoteUserAuthBackend et RemoteUserAuthMiddleware dans un module séparé et de vous y référer dans les paramètres Django .

10
akaihola

Il y a httpauth.py . Je suis toujours un newb complet avec Django donc je n'ai aucune idée de comment il s'intègre exactement, mais il devrait faire ce que vous cherchez.

Edit: voici n fil de bogue plus long sur le sujet .

3
Oli

Cela semble être une tâche pour un AuthenticationBackend personnalisé - voir documentation Django sur ce sujet , djangosnippets.org a quelques exemples réels de ce code (voir 1 = ou 2 ) (et ce n'est pas vraiment difficile).

AuthenticationBackend les sous-classes doivent avoir seulement 2 méthodes définies et leur code est assez simple: l'une doit renvoyer l'objet utilisateur pour l'ID utilisateur, la seconde doit effectuer la vérification des informations d'identification et renvoyer l'objet utilisateur si les informations d'identification sont valides.

0
zgoda

Parce que Django peut être exécuté de plusieurs façons, et seul modpython vous offre une intégration étroite avec Apache, je ne pense pas qu'il existe un moyen pour Django de se connecter) vous en basique sur l'authentification de base d'Apache. L'authentification devrait vraiment être faite au niveau de l'application car cela vous donnera beaucoup plus de contrôle et sera plus simple. Vous ne voulez vraiment pas les tracas de partager des données utilisateur entre Python et Apache.

Si cela ne vous dérange pas d'utiliser une version corrigée de Django alors il y a un correctif sur http://www.djangosnippets.org/snippets/56/ qui vous fournir un middleware pour prendre en charge l'authentification de base.

L'authentification de base est vraiment très simple - si l'utilisateur n'est pas connecté, vous retournez un code d'état requis pour l'authentification 401. Cela invite le navigateur à afficher une boîte de connexion. Le navigateur fournira ensuite le nom d'utilisateur et le mot de passe sous forme de chaînes codées bas64. L'entrée wikipedia http://en.wikipedia.org/wiki/Basic_access_authentication est assez bonne.

Si le patch ne fait pas ce que vous voulez, vous pouvez implémenter vous-même l'authentification de base assez rapidement.

0
Andrew Wilkinson