【问题标题】:Can I use HTTP Basic Authentication with Django?我可以在 Django 中使用 HTTP 基本身份验证吗?
【发布时间】:2010-09-14 05:07:53
【问题描述】:

我们有一个在 Apache 上运行的网站,对其的访问有许多通过 HTTP 基本身份验证保护的静态页面。

我使用 Django 对用户管理的内置支持,使用 Django 编写了网站的新部分。

我遇到的问题是用户必须通过 HTTP 基本身份验证登录一次,然后再次使用 Django 登录表单。这对用户来说既笨拙又非常混乱。

我想知道是否有人找到了让 Django 使用 HTTP 基本身份验证信息登录用户的方法。

我不希望将密码传递给 Django,而是如果用户 dave 已通过 Apache 身份验证,那么他们也应该以 dave 的身份自动登录到 Django。

(一种选择是让 Apache 和 Django 共享一个用户存储以确保通用的用户名和密码,但这仍然会涉及两个登录提示,这是我试图避免的。)

【问题讨论】:

    标签: django http-authentication


    【解决方案1】:

    对于仅支持某些请求的基本身份验证(而不是与网络服务器混为一谈——这就是别人可能会解释您的问题标题的方式),您需要查看这里:

    http://www.djangosnippets.org/snippets/243/

    【讨论】:

      【解决方案2】:

      这已被添加到 Django 1.3 版本中。在此处查看更多当前文档: http://docs.djangoproject.com/en/dev/howto/auth-remote-user/

      【讨论】:

        【解决方案3】:

        请查看 Oli 的链接。通过查看 request.META['REMOTE_USER'],您基本上可以看到在 Django 中由 Basic HTTP Authentication 验证的经过身份验证的用户名。

        更新:测试了票证 #689 的提议补丁,该补丁可在 Telenieko 的 git 存储库 here 中获得最新。它至少适用于 Django 的修订版9084

        通过

        激活远程用户认证后端
        • AuthenticationMiddleware 之后添加RemoteUserAuthMiddleware
        • 添加设置AUTHENTICATION_BACKENDS = ('django.contrib.auth.backends.RemoteUserAuthBackend',)

        如果您像我一样使用 lighttpd 和 FastCGI,请激活 mod_auth,为测试用户创建凭据(我将其命名为 testuser 并将 123 设置为密码)并将 Django 站点配置为需要基本身份验证。

        以下urls.py 可用于测试设置:

        from django.conf.urls.defaults import *
        from django.http import HttpResponse
        from django.contrib.auth.models import User
        urlpatterns = patterns('',
            url(regex='^$',
                view=lambda request: HttpResponse(repr(request), 'text/plain')),
        
            url(regex='^user/$',
                view=lambda request: HttpResponse(repr(request.user), 'text/plain')),
        
            url(regex='^users/$',
                view=lambda request: HttpResponse(
                    ','.join(u.username for u in User.objects.all()),
                    'text/plain')),
        )
        

        在重新加载 lighty 和 Django FCGI 服务器后,加载站点的根目录现在要求身份验证并接受 testuser 凭据,然后输出请求对象的转储。在 request.META 中应该存在这些新属性:

        'AUTH_TYPE': 'Basic'
        'HTTP_AUTHORIZATION': 'Basic dGVzdHVzZXI6MTIz'
        'REMOTE_USER': 'testuser'
        

        /user/ URL 可用于检查您是否确实以testuser 登录:

        <User: testuser>
        

        /users/ URL 现在列出了自动添加的testuser(这里还显示了我在执行syncdb 时创建的admin 用户):

        admin,testuser
        

        如果您不想修补 Django,只需将 RemoteUserAuthBackendRemoteUserAuthMiddleware 类分离到单独的模块中并在 Django 设置中引用它。

        【讨论】:

        • 谢谢。最后,我按照您的建议做了,并将 RemoteUserAuthBackend 和 RemoteUserAuthMiddleware 类放入我自己的模块中,我在 settings.py 中引用了该模块,并且效果很好。
        【解决方案4】:

        httpauth.py。我仍然是 Django 的新手,所以我不知道它是如何完全适应的,但它应该可以满足您的需求。

        编辑:这里是a longer bug thread on the subject

        【讨论】:

          【解决方案5】:

          是的,你可以使用 django 的基本自动化,就像类似的东西:

          def post(self, request):
              auth_header = request.META.get('HTTP_AUTHORIZATION', '')
              token_type, _, credentials = auth_header.partition(' ')
              import base64
              expected = base64.b64encode(b'<username>:<password>').decode()
              if token_type != 'Basic' or credentials != expected:
                  return HttpResponse(status=401)
              authorization success flow code ...
          

          request.META 包含您的 Autorization 所在的关键 HTTP_AUTHORIZATION。

          如果您将 apache 与 modWSGI 一起使用,则密钥 HTTP_AUTHORIZATION 可能不存在。您需要在 WSGI 配置中添加以下行

          WSGIPassAuthorization 开启

          参考这个详细的答案: Passing apache2 digest authentication information to a wsgi script run by mod_wsgi

          希望它对想知道为什么 HTTP_AUTHORIZATION 密钥不存在的人有用

          【讨论】:

            【解决方案6】:

            因为 django 可以通过多种方式运行,并且只有 modpython 可以让您与 Apache 紧密集成,所以我不相信 django 可以通过 Apache 的基本身份验证登录到 basic 中。身份验证应该真正在应用程序级别完成,因为它会给您更多的控制权并且会更简单。您真的不希望在 Python 和 Apache 之间共享用户数据的麻烦。

            如果您不介意使用 Django 的补丁版本,那么http://www.djangosnippets.org/snippets/56/ 有一个补丁,它将为您提供一些支持基本身份验证的中间件。

            基本身份验证非常简单 - 如果用户未登录,您将返回 401 身份验证要求状态码。这会提示浏览器显示一个登录框。然后浏览器将提供用户名和密码作为 bas64 编码字符串。维基百科条目http://en.wikipedia.org/wiki/Basic_access_authentication 相当不错。

            如果补丁不能满足您的要求,那么您可以很快自己实现基本身份验证。

            【讨论】:

              【解决方案7】:

              这似乎是自定义 AuthenticationBackend 的任务 - 请参阅 Django documentation on this subject,djangosn-ps.org 有一些此类代码的真实示例(请参阅 12)(这不是真的很难)。

              AuthenticationBackend 子类必须只定义 2 个方法,并且它们的代码非常简单:一个必须为用户 ID 返回 User 对象,第二个必须执行凭据检查并在凭据有效时返回 User 对象。

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2010-10-04
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多