2011-02-17 41 views
32

我想弄清楚在我的django应用程序中实现基于令牌的身份验证的最佳方式。外部非Django应用程序使用令牌设置cookie,并且我有一个可以基于该令牌检索用户信息的web服务。如果用户设置了Cookie,则他们不需要在我的网站上进行身份验证,并且应该根据Web服务传回的信息自动登录。在我看来,有几个不同的选项来执行实际的检查,我不知道这是最好的:基于令牌的身份验证在Django

  1. 写像在这个snippet的定制的装饰,并用它来代替 login_required
  2. 通过ajax调用在base_site内调用自定义身份验证方法。在每一页上,都会进行检查,如果cookie存在并且有效,那么用户将自动登录。
  3. LOGIN_REDIRECT_URL页面添加一些javascript,以便在ajax调用中检查/验证Cookie,并且如果cookie经过验证,会自动重定向回推荐人。

有没有我缺少的选项?理想情况下,将有一种方法可以将其构建到login_required中,而无需编写自定义装饰器。

回答

20

在搜索代码之前,一定要阅读文档。 http://docs.djangoproject.com/en/1.2/topics/auth/#other-authentication-sources 也读取提供的Django源代码。

你想创造三件事情。

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

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

这里是中间件(编辑)。

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) 

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

这里有一个后端(编辑)

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 

这不会发生重大变化的认证或授权的装饰。

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

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

然而,我们在身份管理器中有复杂的规则和超时,所以我们必须检查每个标记以确保它是有效的。一旦中间件确定令牌有效,我们就可以允许后端执行任何额外的处理。

这不是我们生活的代码(这是一个有点太复杂,使一个很好的例子。)

+1

后端可以简化用户,_ = User.objects.get_or_create(用户名=凭证[“REMOTE_USER”] ) – 2013-03-07 23:43:10

相关问题