43

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

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

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

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

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

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

4

7 回答 7

38

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

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

于 2009-07-06T15:48:56.157 回答
25

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

于 2011-05-04T00:42:10.803 回答
10

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

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

通过以下方式激活远程用户身份验证后端

  • 添加RemoteUserAuthMiddleware之后AuthenticationMiddleware
  • 添加设置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(这里还显示了admin我创建时创建的用户syncdb):

admin,testuser

如果您不想修补 Django,将RemoteUserAuthBackendRemoteUserAuthMiddleware类分离到一个单独的模块中并在 Django 设置中引用它是微不足道的。

于 2008-10-01T07:36:27.347 回答
3

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

编辑:这里有一个关于这个主题的更长的错误线程

于 2008-09-30T08:39:35.440 回答
1

是的,您可以将基本的自动化与 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 密钥不存在的人有用

于 2020-05-26T18:10:58.833 回答
0

因为 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非常好。

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

于 2008-09-30T20:55:26.327 回答
0

这似乎是一项自定义任务AuthenticationBackend- 请参阅有关此主题的 Django 文档,djangosnippets.org 有一些此类代码的真实示例(请参阅12)(这并不是一件难事)。

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

于 2008-10-01T09:14:56.437 回答