基于令牌的身份认证在Django [英] Token Based Authentication in Django

查看:113
本文介绍了基于令牌的身份认证在Django的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图找出在我的django应用程序中实现基于令牌的认证的最佳方法。外部非django应用程序正在使用令牌设置Cookie,并且我有一个Web服务可以根据该标记检索用户信息。如果用户设置了cookie,则不需要在我的站点上进行身份验证,并应根据Web服务传回的信息自动登录。正如我所看到的,执行实际检查有几个不同的选择,我不知道哪个是最好的:


  1. 写一个像片段中的自定义装饰器,并使用它而不是
    login_required

  2. 通过ajax调用在base_site内调用自定义验证方法。在每个页面上,都会进行检查,如果cookie存在且有效,则用户将自动登录。

  3. LOGIN_REDIRECT_URL添加一些javascript 页面,将检查/验证ajax调用中的cookie,并自动重定向到引荐来源,如果cookie通过验证。

有没有选择我失踪?理想情况下,将有一种方式将其构建成 login_required ,而无需编写自定义装饰器。

解决方案

在搜索代码之前,请务必阅读文档。 http://docs.djangoproject.com/en/1.2/topics/auth/#其他认证源
另请阅读提供的Django源。



您要创建三件事。


  1. 中间件捕获令牌。这是大部分工作发生的地方。它检查令牌,通过身份管理器进行身份验证,然后登录用户。


  2. 认证后端查找用户。这是一个存根。它所做的就是根据需要创建用户。您的身份管理员有详细信息。您只是在Django的本地DB上缓存当前版本的用户。


这是中间件(编辑)。

 从django.contrib.auth导入验证,登录

类CookieMiddleware(对象):
使用带有令牌的Cookie的OpenAM的身份验证中间件
后端将获得用户

def process_request(self,request):
如果不是hasattr(request,'user'):
raise不正确的配置()
如果thecookiename不在request.COOKIES:
返回
令牌= request.COOKIES [thecookiename]
#REST请求给OpenAM服务器的用户属性。
token,attribute,role = identity_manager.get_attributes(token)
user = authenticate(remote_user = attribute ['uid'] [0])
request.user = user
login (请求,用户)

identity_manager.get_attributes 是我们写的一个单独的类,用于验证令牌,并从IM源获取用户的详细信息。这当然是为了测试目的而嘲笑的。



这是一个后端(编辑)

  class Backend(RemoteUserBackend):
def authenticate(** credentials):
我们可以通过使用OpenAM
服务器进行身份验证令牌。

try:
user = User.objects.get(username = credentials ['remote_user'])
除了User.DoesNotExist:
user = User.objects.create(username = credentials ['remote_user'])
#这里是将角色映射到Django Group实例或其他功能的好地方。
返回用户

这不会重大更改装饰器的身份验证或授权。 >

为了确保这一点,我们实际上从我们的
身份管理器刷新用户和组信息。



请注意,中间件针对每个请求运行。有时,可以将令牌传递给支持的认证方法。如果令牌存在于本地用户DB中,则该请求可以在不与身份管理器联系的情况下继续进行。



然而,我们在身份管理器中具有复杂的规则和超时,因此我们必须检查每个令牌,以确保它是有效的。一旦中间件确定令牌有效,我们可以允许后端进行任何其他处理。



这不是我们的实时代码(这有点太复杂了做一个很好的例子。)


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 have a webservice that can retrieve user information based off of that token. If the user has the cookie set, they should not need to authenticate on my site and should be automatically logged in based on the info passed back by the web service. As I see it, there are a few different options to perform the actual check and I'm not sure which is best:

  1. Write a custom decorator like the one in this snippet and use it instead of login_required.
  2. Call a custom authenticate method inside base_site through an ajax call. On every page, a check would be made and if the cookie exists and is valid, then the user would be automatically logged in.
  3. Add some javascript to the LOGIN_REDIRECT_URL page that will check/validate the cookie in an ajax call, and automatically redirect back to the referrer if the cookie authenticated.

Is there an option I am missing? Ideally, there would be a way to build this into login_required, without having to write a custom decorator.

解决方案

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.)

这篇关于基于令牌的身份认证在Django的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆