| 1 |
from django.contrib import auth |
|---|
| 2 |
from django.core.exceptions import ImproperlyConfigured |
|---|
| 3 |
|
|---|
| 4 |
|
|---|
| 5 |
class LazyUser(object): |
|---|
| 6 |
def __get__(self, request, obj_type=None): |
|---|
| 7 |
if not hasattr(request, '_cached_user'): |
|---|
| 8 |
from django.contrib.auth import get_user |
|---|
| 9 |
request._cached_user = get_user(request) |
|---|
| 10 |
return request._cached_user |
|---|
| 11 |
|
|---|
| 12 |
|
|---|
| 13 |
class AuthenticationMiddleware(object): |
|---|
| 14 |
def process_request(self, request): |
|---|
| 15 |
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'." |
|---|
| 16 |
request.__class__.user = LazyUser() |
|---|
| 17 |
return None |
|---|
| 18 |
|
|---|
| 19 |
|
|---|
| 20 |
class RemoteUserMiddleware(object): |
|---|
| 21 |
""" |
|---|
| 22 |
Middleware for utilizing web-server-provided authentication. |
|---|
| 23 |
|
|---|
| 24 |
If request.user is not authenticated, then this middleware attempts to |
|---|
| 25 |
authenticate the username passed in the ``REMOTE_USER`` request header. |
|---|
| 26 |
If authentication is successful, the user is automatically logged in to |
|---|
| 27 |
persist the user in the session. |
|---|
| 28 |
|
|---|
| 29 |
The header used is configurable and defaults to ``REMOTE_USER``. Subclass |
|---|
| 30 |
this class and change the ``header`` attribute if you need to use a |
|---|
| 31 |
different header. |
|---|
| 32 |
""" |
|---|
| 33 |
|
|---|
| 34 |
# Name of request header to grab username from. This will be the key as |
|---|
| 35 |
# used in the request.META dictionary, i.e. the normalization of headers to |
|---|
| 36 |
# all uppercase and the addition of "HTTP_" prefix apply. |
|---|
| 37 |
header = "REMOTE_USER" |
|---|
| 38 |
|
|---|
| 39 |
def process_request(self, request): |
|---|
| 40 |
# AuthenticationMiddleware is required so that request.user exists. |
|---|
| 41 |
if not hasattr(request, 'user'): |
|---|
| 42 |
raise ImproperlyConfigured( |
|---|
| 43 |
"The Django remote user auth middleware requires the" |
|---|
| 44 |
" authentication middleware to be installed. Edit your" |
|---|
| 45 |
" MIDDLEWARE_CLASSES setting to insert" |
|---|
| 46 |
" 'django.contrib.auth.middleware.AuthenticationMiddleware'" |
|---|
| 47 |
" before the RemoteUserMiddleware class.") |
|---|
| 48 |
try: |
|---|
| 49 |
username = request.META[self.header] |
|---|
| 50 |
except KeyError: |
|---|
| 51 |
# If specified header doesn't exist then return (leaving |
|---|
| 52 |
# request.user set to AnonymousUser by the |
|---|
| 53 |
# AuthenticationMiddleware). |
|---|
| 54 |
return |
|---|
| 55 |
# If the user is already authenticated and that user is the user we are |
|---|
| 56 |
# getting passed in the headers, then the correct user is already |
|---|
| 57 |
# persisted in the session and we don't need to continue. |
|---|
| 58 |
if request.user.is_authenticated(): |
|---|
| 59 |
if request.user.username == self.clean_username(username, request): |
|---|
| 60 |
return |
|---|
| 61 |
# We are seeing this user for the first time in this session, attempt |
|---|
| 62 |
# to authenticate the user. |
|---|
| 63 |
user = auth.authenticate(remote_user=username) |
|---|
| 64 |
if user: |
|---|
| 65 |
# User is valid. Set request.user and persist user in the session |
|---|
| 66 |
# by logging the user in. |
|---|
| 67 |
request.user = user |
|---|
| 68 |
auth.login(request, user) |
|---|
| 69 |
|
|---|
| 70 |
def clean_username(self, username, request): |
|---|
| 71 |
""" |
|---|
| 72 |
Allows the backend to clean the username, if the backend defines a |
|---|
| 73 |
clean_username method. |
|---|
| 74 |
""" |
|---|
| 75 |
backend_str = request.session[auth.BACKEND_SESSION_KEY] |
|---|
| 76 |
backend = auth.load_backend(backend_str) |
|---|
| 77 |
try: |
|---|
| 78 |
username = backend.clean_username(username) |
|---|
| 79 |
except AttributeError: # Backend has no clean_username method. |
|---|
| 80 |
pass |
|---|
| 81 |
return username |
|---|