32 votes

Authentification basée sur les jetons dans Django

Je suis à essayer de comprendre la meilleure façon de mettre en œuvre jeton d'authentification basée dans mon django app. Un externe, la non-application django est la définition d'un cookie, avec un jeton, et j'ai un webservice qui peuvent récupérer des informations de l'utilisateur en fonction de ce jeton. Si l'utilisateur a le cookie, ils ne devraient pas avoir à s'authentifier sur mon site et devez être connecté automatiquement, basée sur les informations transmises par le service web. Comme je le vois, il y a quelques différentes options pour effectuer la vérification et je ne suis pas sûr de ce qui est le mieux:

  1. Écrire une coutume décorateur, comme celui de cet extrait de code et l'utiliser à la place de login_required.
  2. Appeler une méthode d'authentification personnalisé à l'intérieur de base_site par le biais d'un appel ajax. Sur chaque page, une vérification sera faite et si le cookie existe et est valide, alors l'utilisateur sera connecté automatiquement.
  3. Ajouter un peu de javascript pour l' LOGIN_REDIRECT_URL page, qui va vérifier/valider le biscuit dans un appel ajax, et de rediriger automatiquement de retour au référent si le cookie authentifié.

Est-il une option que je suis absent? Idéalement, il y aurait un moyen de le faire dans login_required, sans avoir à écrire une coutume décorateur.

20voto

S.Lott Points 207588

Avant de rechercher le code, assurez-vous de lire la documentation. http://docs.djangoproject.com/en/1.2/topics/auth/#other-authentication-sources Lire également fournis Django source.

Vous souhaitez créer trois choses.

  1. Middleware pour capturer le pion. C'est là que la plupart du travail se fait. Il vérifie le jeton, authentifie (en confirmant avec le gestionnaire d'identité), puis se connecte à l'utilisateur.

  2. L'authentification backend pour trouver des Utilisateurs. C'est un stub. Il n'est de créer des utilisateurs que nécessaire. Votre identity manager a les détails. Vous êtes tout simplement la mise en cache de la version actuelle de l'utilisateur sur de Django reinhardt, de la bd locale.

Voici le middleware (édité).

from django.contrib.auth import authenticate, login

class CookieMiddleware( object ):
    """Authentication Middleware for OpenAM using a cookie with a token.
    Backend will get user.
    """
    def process_request(self, request):
        if not hasattr(request, 'user'):
            raise ImproperlyConfigured() 
        if "thecookiename" not in request.COOKIES:
            return
        token= request.COOKIES["thecookiename"]
        # REST request to OpenAM server for user attributes.
        token, attribute, role = identity_manager.get_attributes( token )
        user = authenticate(remote_user=attribute['uid'][0])
        request.user = user
        login(request, user)

L' identity_manager.get_attributes est une catégorie distincte, nous avons écrit à valider le jeton et obtenir des détails sur l'utilisateur de la messagerie instantanée source. Ceci, bien entendu, être moqué des fins de test.

Voici un backend (édité)

class Backend( RemoteUserBackend ):
    def authenticate(**credentials):
        """We could authenticate the token by checking with OpenAM
        Server.  We don't do that here, instead we trust the middleware to do it.
        """
        try:
            user= User.objects.get(username=credentials['remote_user'])
        except User.DoesNotExist:
            user= User.objects.create(username=credentials['remote_user'] )
        # Here is a good place to map roles to Django Group instances or other features.
        return user

Ce n'est pas sensiblement changer les décorateurs pour l'authentification ou de l'autorisation.

Pour vous assurer de cela, nous avons fait de rafraîchissement de l'Utilisateur et les informations de Groupe à partir de notre identity manager.

Notez que le middleware pistes pour chaque requête unique. Parfois, il est bon de laisser le jeton à la sauvegarde des authenticate méthode. Si le jeton existe dans le local de la base de données utilisateur, la demande peut se poursuivre sans communiquant avec le gestionnaire d'identité.

Nous avons, néanmoins, ont des règles complexes et les délais d'attente dans le gestionnaire d'identité, nous devons donc examiner chaque jeton pour être sûr qu'elle est valide. Une fois le middleware est sûr que le jeton est valide, on peut alors permettre le backend faire aucun traitement supplémentaire.

Ce n'est pas notre code en direct (c'est un peu trop complexe pour faire un bon exemple).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X