Token Based Authentication in Django

前端 未结 1 1964
灰色年华
灰色年华 2020-12-07 17:35

I am trying to figure out the best way to implement token based authentication in my django app. An external, non-django application is setting a cookie, with a token, and I

相关标签:
1条回答
  • 2020-12-07 18:00

    Before searching for code, be sure you read the documentation. http://docs.djangoproject.com/en/1.2/topics/auth/#other-authentication-sources Also read the supplied Django source.

    You want to create three things.

    1. Middleware to capture the token. This is where most of the work happens. It checks for the token, authenticates it (by confirming it with the identity manager) and then logs in the user.

    2. Authentication backend to find Users. This is a stub. All it does is create users as needed. Your identity manager has the details. You're just caching the current version of the user on Django's local DB.

    Here's the middleware (edited).

    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)
    

    The identity_manager.get_attributes is a separate class we wrote to validate the token and get details on the user from the IM source. This, of course, has to be mocked for testing purposes.

    Here's a backend (edited)

    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
    

    This does not materially change the decorators for authentication or authorization.

    To make sure of this, we actually refresh the User and Group information from our identity manager.

    Note that the middleware runs for every single request. Sometimes, it's okay to pass the token to the backed authenticate method. If the token exists in the local user DB, the request can proceed without contacting the identity manager.

    We, however, have complex rules and timeouts in the identity manager, so we have to examine every token to be sure it's valid. Once the middleware is sure the token is valid, we can then allow the backend to do any additional processing.

    This isn't our live code (it's a little too complex to make a good example.)

    0 讨论(0)
提交回复
热议问题