2009-03-15 13:54:28 +08:00
from django . contrib import auth
2012-09-10 04:25:06 +08:00
from django . contrib . auth import load_backend
from django . contrib . auth . backends import RemoteUserBackend
2009-03-15 13:54:28 +08:00
from django . core . exceptions import ImproperlyConfigured
2011-05-31 23:43:19 +08:00
from django . utils . functional import SimpleLazyObject
2009-03-15 13:54:28 +08:00
2011-05-31 23:43:19 +08:00
def get_user ( request ) :
if not hasattr ( request , ' _cached_user ' ) :
2011-06-06 20:11:48 +08:00
request . _cached_user = auth . get_user ( request )
2011-05-31 23:43:19 +08:00
return request . _cached_user
2006-05-02 09:31:56 +08:00
2009-03-15 13:54:28 +08:00
2006-06-08 13:00:13 +08:00
class AuthenticationMiddleware ( object ) :
2006-05-02 09:31:56 +08:00
def process_request ( self , request ) :
assert hasattr ( request , ' session ' ) , " The Django authentication middleware requires session middleware to be installed. Edit your MIDDLEWARE_CLASSES setting to insert ' django.contrib.sessions.middleware.SessionMiddleware ' . "
2011-05-31 00:33:23 +08:00
2011-05-31 23:43:19 +08:00
request . user = SimpleLazyObject ( lambda : get_user ( request ) )
2009-03-15 13:54:28 +08:00
class RemoteUserMiddleware ( object ) :
"""
2010-10-09 16:12:50 +08:00
Middleware for utilizing Web - server - provided authentication .
2009-03-15 13:54:28 +08:00
If request . user is not authenticated , then this middleware attempts to
authenticate the username passed in the ` ` REMOTE_USER ` ` request header .
If authentication is successful , the user is automatically logged in to
persist the user in the session .
The header used is configurable and defaults to ` ` REMOTE_USER ` ` . Subclass
this class and change the ` ` header ` ` attribute if you need to use a
different header .
"""
# Name of request header to grab username from. This will be the key as
# used in the request.META dictionary, i.e. the normalization of headers to
# all uppercase and the addition of "HTTP_" prefix apply.
header = " REMOTE_USER "
def process_request ( self , request ) :
# AuthenticationMiddleware is required so that request.user exists.
if not hasattr ( request , ' user ' ) :
raise ImproperlyConfigured (
" The Django remote user auth middleware requires the "
" authentication middleware to be installed. Edit your "
" MIDDLEWARE_CLASSES setting to insert "
" ' django.contrib.auth.middleware.AuthenticationMiddleware ' "
" before the RemoteUserMiddleware class. " )
try :
username = request . META [ self . header ]
except KeyError :
2012-09-10 04:25:06 +08:00
# If specified header doesn't exist then remove any existing
# authenticated remote-user, or return (leaving request.user set to
# AnonymousUser by the AuthenticationMiddleware).
if request . user . is_authenticated ( ) :
try :
stored_backend = load_backend ( request . session . get (
auth . BACKEND_SESSION_KEY , ' ' ) )
if isinstance ( stored_backend , RemoteUserBackend ) :
auth . logout ( request )
2013-09-07 12:56:40 +08:00
except ImproperlyConfigured :
2012-09-10 04:25:06 +08:00
# backend failed to load
auth . logout ( request )
2009-03-15 13:54:28 +08:00
return
# If the user is already authenticated and that user is the user we are
# getting passed in the headers, then the correct user is already
# persisted in the session and we don't need to continue.
if request . user . is_authenticated ( ) :
2012-10-13 11:44:50 +08:00
if request . user . get_username ( ) == self . clean_username ( username , request ) :
2009-03-15 13:54:28 +08:00
return
# We are seeing this user for the first time in this session, attempt
# to authenticate the user.
user = auth . authenticate ( remote_user = username )
if user :
# User is valid. Set request.user and persist user in the session
# by logging the user in.
request . user = user
auth . login ( request , user )
def clean_username ( self , username , request ) :
"""
Allows the backend to clean the username , if the backend defines a
clean_username method .
"""
backend_str = request . session [ auth . BACKEND_SESSION_KEY ]
backend = auth . load_backend ( backend_str )
try :
username = backend . clean_username ( username )
2012-10-13 11:44:50 +08:00
except AttributeError : # Backend has no clean_username method.
2009-03-15 13:54:28 +08:00
pass
return username