- September 8, 2009
- middleware decorator http-auth basic-auth
- 2 (after 2 ratings)
Use HTTP Authorization to log in to django site.
If you use the FORCE_HTTP_AUTH=True in your settings.py, then ONLY Http Auth will be used, if you don't then either http auth or django's session-based auth will be used. This assumes that the regular auth middleware is already installed.
If you provide a HTTP_AUTH_REALM in your settings, that will be used as the realm for the challenge.
Having both a decorator and a middleware means that for site-wide http auth, you only need to specify it once, but the same code can be used as a decorator if you want part of your site protected using htty basic auth, and the other bits freely visible.
Of course, since this is basic auth, then you need to make sure your site is running under SSL (HTTPS), else your users passwords are effectively transmitted in the clear.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
""" Use HTTP Authorization to log in to django site. If you use the FORCE_HTTP_AUTH=True in your settings.py, then ONLY Http Auth will be used, if you don't then either http auth or django's session-based auth will be used. If you provide a HTTP_AUTH_REALM in your settings, that will be used as the realm for the challenge. """ from django.conf import settings from django.http import HttpResponse from django.contrib.auth import authenticate import base64 from functools import wraps class HttpAuthMiddleware(object): """ Some middleware to authenticate all requests at this site. """ def process_request(self, request): return _http_auth_helper(request) def http_auth(func): """ A decorator, that can be used to authenticate some requests at the site. """ @wraps(func) def inner(request, *args, **kwargs): result = _http_auth_helper(request) if result is not None: return result return func(request, *args, **kwargs) return inner def _http_auth_helper(request): "This is the part that does all of the work" try: if not settings.FORCE_HTTP_AUTH: # If we don't mind if django's session auth is used, see if the # user is already logged in, and use that user. if request.user: return None except AttributeError: pass # At this point, the user is either not logged in, or must log in using # http auth. If they have a header that indicates a login attempt, then # use this to try to login. if request.META.has_key('HTTP_AUTHORIZATION'): auth = request.META['HTTP_AUTHORIZATION'].split() if len(auth) == 2: if auth.lower() == 'basic': # Currently, only basic http auth is used. uname, passwd = base64.b64decode(auth).split(':') user = authenticate(username=uname, password=passwd) if user: # If the user successfully logged in, then add/overwrite # the user object of this request. request.user = user return None # The username/password combo was incorrect, or not provided. # Challenge the user for a username/password. resp = HttpResponse() resp.status_code = 401 try: # If we have a realm in our settings, use this for the challenge. realm = settings.HTTP_AUTH_REALM except AttributeError: realm = "" resp['WWW-Authenticate'] = 'Basic realm="%s"' % realm return resp