from django.contrib.auth import authenticate from django.http import HttpResponse from django.utils.deprecation import MiddlewareMixin import basicauth class DjangoBasicAuthMiddleware(MiddlewareMixin): """ This middleware should be placed AFTER the standard session-based AuthenticationMiddleware of Django, if this one is used. If request.user is missing or anonymous, this middleware attempts to authenticate the request using basic-auth headers, which must contain valid username/password credentials recognized by one of the AUTHENTICATION_BACKENDS of Django. """ def process_request(self, request): if hasattr(request, "user") and request.user.is_authenticated: return # Don't interfere with standard authentication basic_auth_header = request.META.get("HTTP_AUTHORIZATION") if not basic_auth_header: return try: username, password = basicauth.decode(basic_auth_header) except basicauth.DecodeError: pass # Do not log sensitive data, just let it be user = authenticate(request=request, username=username, password=password) if not user: # Help the client guess the problem, since it attempted basic-auth return HttpResponse("Invalid Basic Auth credentials", status=401) request.user = user # Might override an AnonymousUser