Cómo autenticarse utilizando REMOTE_USER

Este documento describe cómo utilizar fuentes de autenticación externas (donde el servidor web establece la variable de entorno REMOTE_USER) en tus aplicaciones Django. Este tipo de solución de autenticación se ve típicamente en sitios intranet, con soluciones de inicio de sesión único como IIS y Windows Authentication Integrado o Apache y mod_authnz_ldap, CAS, WebAuth, mod_auth_sspi, etc.

Cuando el servidor web se encarga de la autenticación, típicamente establece la variable de entorno REMOTE_USER para su uso en la aplicación subyacente. En Django, REMOTE_USER está disponible en el atributo request.META . Django puede configurarse para utilizar el valor REMOTE_USER utilizando las clases RemoteUserMiddleware o PersistentRemoteUserMiddleware, y RemoteUserBackend encontrados en django.contrib.auth.

Configuración

Primero, debes agregar la clase django.contrib.auth.middleware.RemoteUserMiddleware a la configuración de MIDDLEWARE después de la clase django.contrib.auth.middleware.AuthenticationMiddleware:

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

A continuación, debes reemplazar la clase ModelBackend con RemoteUserBackend en la configuración de AUTHENTICATION_BACKENDS

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

Con esta configuración, RemoteUserMiddleware detectará el nombre de usuario en request.META['REMOTE_USER'] y autenticará y auto-iniciará al usuario utilizando la clase RemoteUserBackend.

Ten en cuenta que esta particular configuración deshabilita la autenticación con el backend por defecto ModelBackend. Esto significa que si el valor REMOTE_USER no está establecido, el usuario no puede iniciar sesión, incluso utilizando la interfaz de administración de Django. Agregar “django.contrib.auth.backends.ModelBackend” a la lista AUTHENTICATION_BACKENDS utilizará ModelBackend como fallback si REMOTE_USER está ausente, lo que resolverá estos problemas.

La gestión de usuarios de Django, como las vistas en contrib.admin y el comando de administración createsuperuser, no integran con los usuarios remotos. Estas interfaces funcionan con usuarios almacenados en la base de datos independientemente de AUTHENTICATION_BACKENDS.

Nota

Dado que la clase RemoteUserBackend hereda de ModelBackend, todavía tendrás todos los mismos controles de permisos implementados en ModelBackend.

Los usuarios con is_active=False no serán permitidos para autenticarse. Utiliza AllowAllUsersRemoteUserBackend si deseas permitirles que lo hagan.

Si tu mecanismo de autenticación utiliza un encabezado HTTP personalizado y no REMOTE_USER, puedes heredar de RemoteUserMiddleware y establecer el atributo header en la clave deseada de request.META. Por ejemplo:

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


 class CustomHeaderRemoteUserMiddleware(RemoteUserMiddleware):
     header = "HTTP_AUTHUSER"

Este middleware personalizado se utiliza luego en la configuración MIDDLEWARE en lugar de django.contrib.auth.middleware.RemoteUserMiddleware:

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

Advertencia

Ten mucho cuidado si utilizas una clase derivada de RemoteUserMiddleware con un encabezado HTTP personalizado. Debes asegurarte de que tu servidor web frontal siempre establezca o elimine ese encabezado según las comprobaciones de autenticación adecuadas, nunca permitiendo a un usuario final enviar un valor falso (o «spoofed») del encabezado. Dado que los encabezados HTTP X-Auth-User y X-Auth_User (por ejemplo) se normalizan en la clave HTTP_X_AUTH_USER de request.META, también debes comprobar que tu servidor web no permite un encabezado spoofed utilizando guiones bajos en lugar de guiones.

Esta advertencia no se aplica a RemoteUserMiddleware en su configuración por defecto con header = 'REMOTE_USER', ya que una clave que no comienza con HTTP_ en request.META solo puede ser establecida por tu servidor WSGI, y no directamente desde un encabezado HTTP.

Si necesitas más control, puedes crear tu propio backend de autenticación que herede de RemoteUserBackend y sobreescribas uno o más de sus atributos y métodos.

Utilizar REMOTE_USER solo en páginas de inicio de sesión

El middleware de autenticación RemoteUserMiddleware asume que el encabezado HTTP REMOTE_USER está presente con todas las solicitudes autenticadas. Eso podría ser lo esperado y práctico cuando se utiliza Basic HTTP Auth con htpasswd o mecanismos similares, pero con Negotiate (GSSAPI/Kerberos) u otros métodos de autenticación intensivos en recursos, la autenticación en el servidor web frontal suele configurarse solo para una o pocas URL de inicio de sesión, y después del inicio de sesión exitoso, la aplicación debe mantener la sesión autenticada por sí misma.

La clase PersistentRemoteUserMiddleware proporciona soporte para este caso de uso. Mantendrá la sesión autenticada hasta que el usuario realice un cierre de sesión explícito. La clase se puede utilizar como reemplazo directo de RemoteUserMiddleware en la documentación anterior.