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 RemoteUserMiddleware
or 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
:
- MIDDLEWARE = [
- '...',
- 'django.contrib.auth.middleware.AuthenticationMiddleware',
- 'django.contrib.auth.middleware.RemoteUserMiddleware',
- '...',
- ]
Next, you must replace the ModelBackend
with RemoteUserBackend
in theAUTHENTICATION_BACKENDS
setting:
- AUTHENTICATION_BACKENDS = [
- 'django.contrib.auth.backends.RemoteUserBackend',
- ]
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:
- from django.contrib.auth.middleware import RemoteUserMiddleware
- class CustomHeaderMiddleware(RemoteUserMiddleware):
- 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.
PersistentRemoteUserMiddleware
provides 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 RemoteUserMiddleware
in the documentation above.