我可以在Django中使用HTTP基本身份验证吗?

时间:2008-09-30 08:34:35

标签: django http-authentication

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

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

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

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

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

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

7 个答案:

答案 0 :(得分:34)

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

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

答案 1 :(得分:24)

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

答案 2 :(得分:10)

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

更新:测试了票据#689的建议补丁,该补丁在telenieko的git存储库here中是最新的。它至少适用于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/网址可​​用于检查您确实以[{1}}身份登录:

testuser

<User: testuser> 网址现在列出了自动添加的/users/(此处显示了testuser时创建的admin用户):

syncdb

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

答案 3 :(得分:3)

httpauth.py。我仍然是Django的完全新手,所以我不知道它是如何完全适合的,但它应该做你想要的。

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

答案 4 :(得分:0)

因为django可以通过多种方式运行,并且只有modpython可以让你与Apache紧密集成,所以我认为django没有办法让你在Apache的基本身份验证基础上登录。身份验证应该在应用程序级别完成,因为它将为您提供更多控制并且更简单。你真的不想在Python和Apache之间共享用户数据的麻烦。

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

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

如果补丁没有达到您想要的效果,那么您可以很快自己实现基本身份验证。

答案 5 :(得分:0)

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

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

答案 6 :(得分:0)

是的,您可以在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包含密钥HTTP_AUTHORIZATION,其中存在您的自动操作。

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

WSGIPassAuthorization启用

请参考以下详细答案: Passing apache2 digest authentication information to a wsgi script run by mod_wsgi

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

相关问题