|
0
|
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 |