Authentication using REMOTE_USER

This document describes how to make use of external authentication sources(where the Web server sets the REMOTE_USER environment variable) in yourDjango applications. This type of authentication solution is typically seen onintranet sites, with single sign-on solutions such as IIS and IntegratedWindows 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 theREMOTE_USER environment variable for use in the underlying application. InDjango, REMOTE_USER is made available in the request.META attribute. Django can be configured to makeuse of the REMOTE_USER value using the RemoteUserMiddlewareor PersistentRemoteUserMiddleware, andRemoteUserBackend classes found indjango.contrib.auth.

Configuration

First, you must add thedjango.contrib.auth.middleware.RemoteUserMiddleware to theMIDDLEWARE setting after thedjango.contrib.auth.middleware.AuthenticationMiddleware:

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

Next, you must replace the ModelBackendwith RemoteUserBackend in theAUTHENTICATION_BACKENDS setting:

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

With this setup, RemoteUserMiddleware will detect the username inrequest.META['REMOTE_USER'] and will authenticate and auto-login that userusing the RemoteUserBackend.

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

Django’s user management, such as the views in contrib.admin andthe createsuperuser management command, doesn’t integrate withremote users. These interfaces work with users stored in the databaseregardless of AUTHENTICATION_BACKENDS.

Note

Since the RemoteUserBackend inherits from ModelBackend, you willstill have all of the same permissions checking that is implemented inModelBackend.

Users with is_active=False won’t be allowed toauthenticate. UseAllowAllUsersRemoteUserBackend ifyou want to allow them to.

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

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

Warning

Be very careful if using a RemoteUserMiddleware subclass with a customHTTP header. You must be sure that your front-end web server always sets orstrips that header based on the appropriate authentication checks, neverpermitting an end-user to submit a fake (or “spoofed”) header value. Sincethe HTTP headers X-Auth-User and X-Auth_User (for example) bothnormalize to the HTTP_X_AUTH_USER key in request.META, you mustalso check that your web server doesn’t allow a spoofed header usingunderscores in place of dashes.

This warning doesn’t apply to RemoteUserMiddleware in its defaultconfiguration with header = 'REMOTEUSER', since a key that doesn’tstart with HTTP in request.META can only be set by your WSGIserver, not directly from an HTTP request header.

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

Using REMOTE_USER on login pages only

The RemoteUserMiddleware authentication middleware assumes that the HTTPrequest header REMOTE_USER is present with all authenticated requests. Thatmight be expected and practical when Basic HTTP Auth with htpasswd orsimilar mechanisms are used, but with Negotiate (GSSAPI/Kerberos) or otherresource intensive authentication methods, the authentication in the front-endHTTP server is usually only set up for one or a few login URLs, and aftersuccessful authentication, the application is supposed to maintain theauthenticated session itself.

PersistentRemoteUserMiddlewareprovides support for this use case. It will maintain the authenticated sessionuntil explicit logout by the user. The class can be used as a drop-inreplacement of RemoteUserMiddlewarein the documentation above.