Django - 加载具有外部身份验证的页面会更改session_key

时间:2013-04-09 07:48:35

标签: django session authentication

我正在尝试将项目从Django 1.4迁移到Django 1.5.1 ...

必须可以通过身份验证和匿名用户访问Web服务。我们对Apache模块使用外部认证(根据https://docs.djangoproject.com/en/1.5/howto/auth-remote-user/设置“REMOTE_USER”env var。)

网址https://example.com/具有不同的内容,具体取决于用户是匿名还是经过身份验证。

我们与Django 1.4一起使用的策略是,只有以/ auth /开头的URL由Apache的模块进行身份验证。如果用户(在页面https://example.com/上)选择进行身份验证,则会跳转到https://example.com/auth/。 / auth /由Apache的模块进行身份验证,然后由Django应用程序提供服务,该应用程序重定向回https://example.com/。由于session_key,Django知道用户已经过身份验证。

不幸的是,使用Django 1.5.1 ...每次浏览器从经过身份验证的URL移动到未经过身份验证的URL时,session_key都会更改。

在我的日志中,我可以看到(Django 1.5.1):

DEBUG 2013-04-09 09:15:20,571 views home None
DEBUG 2013-04-09 09:15:48,886 views auth ow1bzgdajs7i12d9bmfwwm3fpw47elna
DEBUG 2013-04-09 09:15:48,981 views home mehlf1x0iemx9yc3ddf6mhnls1nha1r4
  • 第一行是用户访问https://example.com/
  • 第二次点击按钮“Connexion”。
  • 第三个是/。
  • 的HttpResponseRedirect
  • 最后一个字符串是request.session.session_key。

当我删除/ auth(Django 1.5.1)上的apache身份验证时:

DEBUG 2013-04-09 09:16:45,268 views home None
DEBUG 2013-04-09 09:16:48,258 views auth None
DEBUG 2013-04-09 09:16:48,345 views home None

使用Django 1.4,这是同一个日志给出的内容:

DEBUG 2013-04-09 09:11:21,899 views home None
DEBUG 2013-04-09 09:11:41,261 views auth f16ab3e574b866177803f9011dc33ab8
DEBUG 2013-04-09 09:11:41,375 views home f16ab3e574b866177803f9011dc33ab8

预期这种行为会发生变化吗? (新功能?) 我们怎么能解决它?

谢谢!

2 个答案:

答案 0 :(得分:3)

这是一个错误修正:https://code.djangoproject.com/ticket/17869

Django 1.5的发行说明中记录了它:

  

RemoteUserMiddleware现在强制在同一浏览器会话期间REMOTE_USER标头消失时注销。

答案 1 :(得分:1)

正如Aymeric所提到的,这是一个出现在Django 1.5中的预期错误修正。 :) :(

在我们的例子中,即使Apache的模块不再提供“REMOTE_USER”变量,我们仍然需要会话持续存在。 为了解决这个问题,我发现了两种可能性:

  1. 子类RemoteUserMiddleware并仅重新定义process_request方法,而不使用代码段auth.logout(request)
  2. 在需要时插入一个将用户名注入REMOTE_USER的自制中间件。
  3. 我选择了第二种可能性,因为它将/应该是零努力以适应即将推出的Django版本。

    在我的settings.py中,我在'main.middleware.persistant_session_middleware'

    之前添加了'django.contrib.auth.middleware.RemoteUserMiddleware'

    并在main / middleware.py中定义 persistant_session_middleware

    class persistant_session_middleware(object):
    def __init__(self):
        pass
    
    def process_request(self, request):
        header = "REMOTE_USER"
    
        if request.user.is_authenticated() and not header in request.META:
            request.META[header] = request.user.username
        return None
    

    我只希望这不会是一个安全漏洞!但只要它取决于request.user.is_authenticated()我认为我们是安全的:)