# Django 5.2.8 documentation

# 使用 `REMOTE_USER` 进行身份验证

This document describes how to make use of external authentication sources (where the web server sets the `REMOTE_USER` environment variable) 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 sets the `REMOTE_USER` environment variable for use in the underlying application. In Django, `REMOTE_USER` is made available in the `request.META` attribute. 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`.

## 配置

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

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

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

    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` 为何值。

Note

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

具有 `is_active=False` 的用户将被禁止验证。你可以使用 `AllowAllUsersRemoteUserBackend` 来允许验证。

If your authentication mechanism uses a custom HTTP header and not `REMOTE_USER`, you can subclass `RemoteUserMiddleware` and set the `header` attribute to the desired `request.META` key. For example:

`mysite/middleware.py`

     from django.contrib.auth.middleware import RemoteUserMiddleware

     class CustomHeaderRemoteUserMiddleware(RemoteUserMiddleware):
         header = "HTTP_AUTHUSER"

This custom middleware is then used in the `MIDDLEWARE` setting instead of `django.contrib.auth.middleware.RemoteUserMiddleware`:

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

Warning

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

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