使用 REMOTE_USER 进行身份验证

这篇文档讲述了如何在你的 Django 应用中使用外部身份验证资源(在web服务器上设置 ``REMOTE_USER``的地方)。这种类型的身份验证方法一般用在使用了单点登录方案的内部网站上,比如 IIS 和 Windows 一体化验证或者 Apache 和 mod_authnz_ldap, CAS, Cosign, WebAuth, `mod_auth_sspi`_等等。

当Web服务器负责鉴权时,通常设置``REMOTE_USER``这个环境变量为了在底层应用中使用。在Django中,REMOTE_USER``是作为:attr:`request.META <django.http.HttpRequest.META>` 的参数来使用的。如果想在Django中使用``REMOTE_USER, 可以通过配置``RemoteUserMiddleware`` 中间件,``PersistentRemoteUserMiddleware``中间件,或者继承在 django.contrib.auth`中的:class:`~django.contrib.auth.backends.RemoteUserBackend 来实现。

配置

首先,你需要向配置文件的:setting:MIDDLEWARE`键中,在:class:`django.contrib.auth.middleware.AuthenticationMiddleware:: 的**后面**添加:class:django.contrib.auth.middleware.RemoteUserMiddleware :

MIDDLEWARE = [
    '...',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.auth.middleware.RemoteUserMiddleware',
    '...',
]

然后,你需要将设置中的:setting:AUTHENTICATION_BACKENDS setting:: 键值由:class:~django.contrib.auth.backends.ModelBackend  替换为:class:~django.contrib.auth.backends.RemoteUserBackend

AUTHENTICATION_BACKENDS = [
    'django.contrib.auth.backends.RemoteUserBackend',
]

通过此项设置, RemoteUserMiddleware 可以检测``request.META['REMOTE_USER']`` 中的用户名,而且可以认证和自动登录用户使用的:class:~django.contrib.auth.backends.RemoteUserBackend.

要注意这项设置将导致无法使用默认的``ModelBackend``验证。也就是说如果``REMOTE_USER``的值没有指定则该用户将无法登录,即使通过Django的管理后台。要解决这些问题,把``'django.contrib.auth.backends.ModelBackend'加入``AUTHENTICATION_BACKENDS``列表中,则当``REMOTE_USER``未指定时,就会回退使用``ModelBackend

Django的用户管理系统,比如``contrib.admin``中的视图函数及:djadmin:`createsuperuser`的管理命令,都没有与远程用户集成。这些接口只工作在数据库中存储的用户上,无论``AUTHENTICATION_BACKENDS``为何值。

注解

因为 RemoteUserBackend 继承自 ModelBackend, 您仍将拥有在 ModelBackend 中实现的所有相同的权限检查。

具有:attr:`is_active=False <django.contrib.auth.models.User.is_active>`的用户将被禁止验证。你可以使用:class:`~django.contrib.auth.backends.AllowAllUsersRemoteUserBackend`来允许验证。

如果你的验证机制使用一个自定义的HTTP头部而不是``REMOTE_USER``,你可以构建一个``RemoteUserMiddleWare``的子类然后把``header``属性设成你希望的``request.META``键值。例如:

from django.contrib.auth.middleware import RemoteUserMiddleware

class CustomHeaderMiddleware(RemoteUserMiddleware):
    header = 'HTTP_AUTHUSER'

警告

使用具有自定义HTTP头部的``RemoteUserMiddleware``子类时需要特别小心。你要确保你的前端服务器基于验证检查结果正确设置或去除了该头部,禁止任何终端用户提交一个仿冒的头部值。因为HTTP头部``X-Auth-User``与(比方说)``X-Auth_User``都会标准化为``request.META``的``HTTP_X_AUTH_USER``键,你必须确保你的服务器不允许头部使用下划线来替代横杠。

这个警告不适用于 RemoteUserMiddlewar,它的默认配置为 header ='REMOTE_USER', 因为在 request.META 中不存在以 HTTP_ 开始的键可以只由WSGI服务器设置, 而不能直接来自HTTP请求头部.

如果你需要更多控制, 你可以通过继承 RemoteUserBackend 并且覆盖其一个或多个属性和方法来创建你自己的验证后端.

仅在登录界面使用 REMOTE_USER

``RemoteUserMiddleware``验证中间件假定所有已验证的请求都包含``REMOTE_USER``头部。这可能对于使用``htpasswd``或其他简单机制的基础HTTP验证方式是很自然的,然而对于协商验证(GSSAP/Kerberos)或其他资源密集的验证方式来说,前端HTTP服务器的验证通常只在几个登录的URL上存在,在验证成功之后,应用需要自己维护已验证的会话。

RemoteUserMiddleware