使用 REMOTE_USER 进行身份验证

这篇文档讲述了如何在你的 Django 应用中使用外部身份验证资源(在web服务器上设置 ``REMOTEUSER`的地方)。这种类型的身份验证方法一般用在使用了单点登录方案的内部网站上,比如 IIS 和 Windows 一体化验证或者 Apache 和 [mod_authnz_ldap](https://httpd.apache.org/docs/2.2/mod/mod_authnz_ldap.html), [CAS](https://www.apereo.org/projects/cas), [Cosign](http://weblogin.org), [WebAuth](https://www.stanford.edu/services/webauth/), [](#id3)mod_auth_sspi`等等。

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

配置

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

  1. MIDDLEWARE = [
  2. '...',
  3. 'django.contrib.auth.middleware.AuthenticationMiddleware',
  4. 'django.contrib.auth.middleware.RemoteUserMiddleware',
  5. '...',
  6. ]

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

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

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

要注意这项设置将导致无法使用默认的ModelBackend验证。也就是说如果REMOTE_USER的值没有指定则该用户将无法登录,即使通过Django的管理后台。要解决这些问题,把&#39;django.contrib.auth.backends.ModelBackend&#39;<code>加入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:[](#id3)~django.contrib.auth.backends.AllowAllUsersRemoteUserBackend`来允许验证。

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

  1. from django.contrib.auth.middleware import RemoteUserMiddleware
  2.  
  3. class CustomHeaderMiddleware(RemoteUserMiddleware):
  4. header = 'HTTP_AUTHUSER'

警告

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

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

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

仅在登录界面使用 REMOTE_USER

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

RemoteUserMiddleware