2009-03-15 13:54:28 +08:00
from django . contrib import auth
from django . core . exceptions import ImproperlyConfigured
2006-05-02 09:31:56 +08:00
class LazyUser ( object ) :
def __get__ ( self , request , obj_type = None ) :
2006-09-13 01:30:47 +08:00
if not hasattr ( request , ' _cached_user ' ) :
2006-06-29 00:37:02 +08:00
from django . contrib . auth import get_user
2006-09-13 01:30:47 +08:00
request . _cached_user = get_user ( request )
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 ' . "
request . __class__ . user = LazyUser ( )
return None
2009-03-15 13:54:28 +08:00
class RemoteUserMiddleware ( object ) :
"""
Middleware for utilizing web - server - provided authentication .
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 :
# If specified header doesn't exist then return (leaving
# request.user set to AnonymousUser by the
# AuthenticationMiddleware).
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 ( ) :
if request . user . username == self . clean_username ( username , request ) :
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 )
except AttributeError : # Backend has no clean_username method.
pass
return username