使用 REMOTE_USER 进行身份验证Link to this heading

This document describes how to make use of external authentication sources in your Django applications. This type of authentication solution is typically seen on intranet sites, with single sign-on solutions such as IIS and Integrated Windows Authentication or Apache and mod_authnz_ldap, CAS, WebAuth, mod_auth_sspi, etc.

When the web server takes care of authentication it typically provides the authenticated user as REMOTE_USER. In Django, this value is made available in request.META (as REMOTE_USER when supplied as an environment variable, as in WSGI, or HTTP_REMOTE_USER when supplied via an HTTP header, as in ASGI). Django can be configured to make use of the REMOTE_USER value using the RemoteUserMiddleware or PersistentRemoteUserMiddleware, and RemoteUserBackend classes found in django.contrib.auth.

配置Link to this heading

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

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

然后,你需要将设置中的 AUTHENTICATION_BACKENDS setting 键值由 ModelBackend 替换为 RemoteUserBackend

Code
AUTHENTICATION_BACKENDS = [
    "django.contrib.auth.backends.RemoteUserBackend",
]

With this setup, RemoteUserMiddleware will detect the username in request.META['REMOTE_USER'] (or request.META['HTTP_REMOTE_USER'] under ASGI) and will authenticate and auto-login that user using the RemoteUserBackend.

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

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

如果你的认证机制使用自定义 HTTP 头而非 REMOTE_USER,你可以继承 RemoteUserMiddleware 并将 header 属性设为所需的 request.META 键名。例如:

mysite/middleware.py
Python
 from django.contrib.auth.middleware import RemoteUserMiddleware


 class CustomHeaderRemoteUserMiddleware(RemoteUserMiddleware):
     header = "HTTP_AUTHUSER"

这个自定义中间件随后将在 MIDDLEWARE 设置中替代 django.contrib.auth.middleware.RemoteUserMiddleware 被使用:

Code
MIDDLEWARE = [
    "...",
    "django.contrib.auth.middleware.AuthenticationMiddleware",
    "mysite.middleware.CustomHeaderRemoteUserMiddleware",
    "...",
]

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

仅在登录界面使用 REMOTE_USERLink to this heading

RemoteUserMiddleware 这个认证中间件 ,它假设HTTP请求的头部 REMOTE_USER 在所有认证请求中都存在。这个假设在当通过 htpasswd 或者相似的认证机制来做Basic HTTP的认证时才是可行的,但是使用Negotiate (GSSAPI/Kerberos) 或者其它资源密集型的认证方法时就说不过去了,前端HTTP server的认证通常用在仅仅一个或不太多的登录URLs,而且在认证成功后,应用还要自己去维护这个session。

PersistentRemoteUserMiddleware 就针对这个使用场景提供了支持。除非用户显式地退出登录,它将一直保留已认证的会话。这个中间件可以代替上文中的 RemoteUserMiddleware