How to authenticate using REMOTE_USERLink to this heading

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, Cosign, 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.

ConfigurationLink to this heading

First, you must add the django.contrib.auth.middleware.RemoteUserMiddleware to the MIDDLEWARE setting after the django.contrib.auth.middleware.AuthenticationMiddleware:

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

Next, you must replace the ModelBackend with RemoteUserBackend in the AUTHENTICATION_BACKENDS setting:

Code
AUTHENTICATION_BACKENDS = [
    'django.contrib.auth.backends.RemoteUserBackend',
]

With this setup, RemoteUserMiddleware will detect the username in request.META['REMOTE_USER'] and will authenticate and auto-login that user using the RemoteUserBackend.

Be aware that this particular setup disables authentication with the default ModelBackend. This means that if the REMOTE_USER value is not set then the user is unable to log in, even using Django’s admin interface. Adding 'django.contrib.auth.backends.ModelBackend' to the AUTHENTICATION_BACKENDS list will use ModelBackend as a fallback if REMOTE_USER is absent, which will solve these issues.

Django’s user management, such as the views in contrib.admin and the createsuperuser management command, doesn’t integrate with remote users. These interfaces work with users stored in the database regardless of AUTHENTICATION_BACKENDS.

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:

Code
from django.contrib.auth.middleware import RemoteUserMiddleware

class CustomHeaderMiddleware(RemoteUserMiddleware):
    header = 'HTTP_AUTHUSER'

If you need more control, you can create your own authentication backend that inherits from RemoteUserBackend and override one or more of its attributes and methods.

Using REMOTE_USER on login pages onlyLink to this heading

The RemoteUserMiddleware authentication middleware assumes that the HTTP request header REMOTE_USER is present with all authenticated requests. That might be expected and practical when Basic HTTP Auth with htpasswd or similar mechanisms are used, but with Negotiate (GSSAPI/Kerberos) or other resource intensive authentication methods, the authentication in the front-end HTTP server is usually only set up for one or a few login URLs, and after successful authentication, the application is supposed to maintain the authenticated session itself.

PersistentRemoteUserMiddleware provides support for this use case. It will maintain the authenticated session until explicit logout by the user. The class can be used as a drop-in replacement of RemoteUserMiddleware in the documentation above.