使用 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"
这个自定义中间件随后将在 MIDDLEWARE 设置中替代 django.contrib.auth.middleware.RemoteUserMiddleware 被使用:
MIDDLEWARE = [
"...",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"mysite.middleware.CustomHeaderRemoteUserMiddleware",
"...",
]
Warning
RemoteUserMiddleware must not be deployed in configurations where a
client can supply the header. You must be sure that your web server or
reverse proxy always sets or strips that header based on the appropriate
authentication checks, never permitting an end user to submit a fake (or
"spoofed") header value. In particular, ASGI deployments cannot be exposed
directly to the internet (that is, without a reverse proxy) when using this
middleware.
Since the HTTP headers X-Auth-User and X-Auth_User (for example)
both normalize to the HTTP_X_AUTH_USER key in request.META, you
must also check that your web server doesn't allow a spoofed header using
underscores in place of dashes.
Under WSGI, this warning doesn't apply to RemoteUserMiddleware in its
default configuration with header = "REMOTE_USER", since a key that
doesn't start with HTTP_ in request.META can only be set by your
WSGI server, not directly from an HTTP request header. This warning does
apply by default on ASGI, because in the async path, the middleware
prepends HTTP_ to the defined header name before looking it up in
request.META.
如果你需要更多控制, 你可以通过继承 RemoteUserBackend 并且覆盖其一个或多个属性和方法来创建你自己的验证后端.
仅在登录界面使用 REMOTE_USER¶
RemoteUserMiddleware 这个认证中间件 ,它假设HTTP请求的头部 REMOTE_USER 在所有认证请求中都存在。这个假设在当通过 htpasswd 或者相似的认证机制来做Basic HTTP的认证时才是可行的,但是使用Negotiate (GSSAPI/Kerberos) 或者其它资源密集型的认证方法时就说不过去了,前端HTTP server的认证通常用在仅仅一个或不太多的登录URLs,而且在认证成功后,应用还要自己去维护这个session。
PersistentRemoteUserMiddleware 就针对这个使用场景提供了支持。除非用户显式地退出登录,它将一直保留已认证的会话。这个中间件可以代替上文中的 RemoteUserMiddleware。