如何使用 REMOTE_USER 进行身份验证

本文档介绍如何在 Django 应用程序中使用外部身份验证源(Web 服务器设置 REMOTE_USER 环境变量)。这种类型的身份验证解决方案通常在内联网站点中使用,并使用诸如 IIS 和集成 Windows 身份验证或 Apache 和 mod_authnz_ldapCASWebAuthmod_auth_sspi 等单点登录解决方案。

当 Web 服务器负责身份验证时,它通常会设置 REMOTE_USER 环境变量以供底层应用程序使用。在 Django 中,REMOTE_USERrequest.META 属性中可用。Django 可以配置为使用 RemoteUserMiddlewarePersistentRemoteUserMiddlewareRemoteUserBackend 类(位于 django.contrib.auth 中)来利用 REMOTE_USER 值。

配置

首先,必须将 django.contrib.auth.middleware.RemoteUserMiddleware 添加到 MIDDLEWARE 设置中,位于 django.contrib.auth.middleware.AuthenticationMiddleware **之后**。

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

接下来,必须在 AUTHENTICATION_BACKENDS 设置中用 RemoteUserBackend 替换 ModelBackend

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

通过此设置,RemoteUserMiddleware 将检测 request.META['REMOTE_USER'] 中的用户名,并使用 RemoteUserBackend 对该用户进行身份验证并自动登录。

请注意,此特定设置会禁用默认 ModelBackend 的身份验证。这意味着,如果未设置 REMOTE_USER 值,则用户将无法登录,即使使用 Django 的管理界面也是如此。将 'django.contrib.auth.backends.ModelBackend' 添加到 AUTHENTICATION_BACKENDS 列表中将在 REMOTE_USER 缺失时使用 ModelBackend 作为后备,这将解决这些问题。

Django 的用户管理(例如 contrib.admin 中的视图和 createsuperuser 管理命令)不与远程用户集成。这些界面与存储在数据库中的用户一起工作,而不管 AUTHENTICATION_BACKENDS 如何。

注意

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

具有 is_active=False 的用户将无法进行身份验证。如果要允许他们,请使用 AllowAllUsersRemoteUserBackend

如果您的身份验证机制使用自定义 HTTP 标头而不是 REMOTE_USER,则可以对 RemoteUserMiddleware 进行子类化,并将 header 属性设置为所需的 request.META 键。例如

from django.contrib.auth.middleware import RemoteUserMiddleware


class CustomHeaderMiddleware(RemoteUserMiddleware):
    header = "HTTP_AUTHUSER"

警告

如果将 RemoteUserMiddleware 子类与自定义 HTTP 标头一起使用,请务必小心。您必须确保您的前端 Web 服务器始终根据适当的身份验证检查设置或剥离该标头,绝不允许最终用户提交伪造的(或“欺骗的”)标头值。由于 HTTP 标头 X-Auth-UserX-Auth_User(例如)都规范化为 request.META 中的 HTTP_X_AUTH_USER 键,因此您还必须检查您的 Web 服务器是否不允许使用下划线代替连字符来伪造标头。

此警告不适用于其默认配置中使用 header = 'REMOTE_USER'RemoteUserMiddleware,因为 request.META 中不以 HTTP_ 开头的键只能由您的 WSGI 服务器设置,而不能直接从 HTTP 请求标头设置。

如果您需要更多控制,可以创建自己的身份验证后端,该后端继承自 RemoteUserBackend 并覆盖其一个或多个属性和方法。

仅在登录页面上使用 REMOTE_USER

RemoteUserMiddleware 身份验证中间件假设 HTTP 请求标头 REMOTE_USER 存在于所有已认证的请求中。当使用 htpasswd 或类似机制的基本 HTTP 身份验证时,这可能是预期和实用的,但是对于协商(GSSAPI/Kerberos)或其他资源密集型身份验证方法,前端 HTTP 服务器中的身份验证通常仅针对一个或几个登录 URL 设置,并且在成功身份验证后,应用程序应该自行维护已认证的会话。

PersistentRemoteUserMiddleware 为此用例提供了支持。它将维护已认证的会话,直到用户显式注销。该类可以用作上面文档中 RemoteUserMiddleware 的直接替换。

返回顶部