2011-02-17 17 views
32

Estoy tratando de encontrar la mejor manera de implementar la autenticación basada en tokens en mi aplicación django. Una aplicación externa que no es django está configurando una cookie, con un token, y tengo un servicio web que puede recuperar información del usuario basada en ese token. Si el usuario tiene el conjunto de cookies, no deberían necesitar autenticarse en mi sitio y deberían iniciar sesión automáticamente en función de la información transmitida por el servicio web. Tal como lo veo, hay algunas opciones diferentes para realizar la verificación real y no estoy seguro de que es mejor:Autenticación basada en tokens en Django

  1. Escribir un decorador personalizado como el de esta snippet y usarlo en lugar de login_required.
  2. Llamar a un método de autentificación personalizado dentro de base_site a través de una llamada ajax. En cada página, se realizaría una verificación y si la cookie existe y es válida, entonces el usuario iniciaría sesión automáticamente.
  3. Agregue un javascript a la página LOGIN_REDIRECT_URL que comprobará/validará la cookie en una llamada ajax, y redirigir automáticamente a la referencia si la cookie se autenticó.

¿Existe una opción que me falta? Idealmente, habría una forma de compilar esto en login_required, sin tener que escribir un decorador personalizado.

Respuesta

20

Antes de buscar el código, asegúrese de leer la documentación. http://docs.djangoproject.com/en/1.2/topics/auth/#other-authentication-sources Lea también la fuente de Django suministrada.

Quiere crear tres cosas.

  1. Middleware para capturar el token. Aquí es donde sucede la mayor parte del trabajo. Comprueba el token, lo autentica (confirmándolo con el administrador de identidad) y luego inicia sesión en el usuario.

  2. Backend de autenticación para encontrar usuarios. Este es un stub. Todo lo que hace es crear usuarios según sea necesario. Su administrador de identidad tiene los detalles. Simplemente está almacenando en caché la versión actual del usuario en la base de datos local de Django.

Aquí está el middleware (editado).

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) 

El identity_manager.get_attributes es una clase separada escribimos para validar el token y obtener detalles sobre el usuario de la fuente de mensajería instantánea. Esto, por supuesto, tiene que ser burlado para fines de prueba.

Aquí es un backend (editado)

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 

Esto no cambia materialmente los decoradores para la autenticación o autorización.

Para estar seguro de esto, en realidad actualizamos la información de Usuario y Grupo de nuestro administrador de identidades.

Tenga en cuenta que el middleware se ejecuta para cada solicitud. A veces, está bien pasar el token al método authenticate respaldado. Si el token existe en la base de datos del usuario local, la solicitud puede continuar sin comunicarse con el administrador de identidad.

Nosotros, sin embargo, tenemos reglas y tiempos de espera complejos en el administrador de identidades, por lo que debemos examinar cada token para asegurarnos de que sea válido. Una vez que el middleware está seguro de que el token es válido, podemos permitir que el back-end realice un procesamiento adicional.

Este no es nuestro código en vivo (que es un poco demasiado complejo para hacer un buen ejemplo.)

+1

backend podría simplificarse en el usuario, _ = User.objects.get_or_create credenciales (nombre de usuario = [ 'usuario_remoto']) –

Cuestiones relacionadas