Django中基于令牌的身份验证

Bac*_*con 32 django

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

  1. 编写一个自定义装饰器,就像这个片段中的那个一样,而不是使用它 login_required.
  2. 通过ajax调用在base_site中调用自定义身份验证方法.在每个页面上,都会进行检查,如果cookie存在且有效,则用户将自动登录.
  3. 将一些javascript添加到LOGIN_REDIRECT_URL将在ajax调用中检查/验证cookie 的页面,并在cookie经过身份验证时自动重定向回引用者.

我有遗失的选择吗?理想情况下,有一种方法可以将其构建login_required,而无需编写自定义装饰器.

S.L*_*ott 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)
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

这不会实质性地更改装饰器以进行身份​​验证或授权.

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

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

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

这不是我们的实时代码(它有点太复杂,不能成为一个好例子.)