middleware for utilizing webserverprovided authentication if request user is not authenticated then this middleware attempts to authenticate the username passed in the remoteuser 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 remoteuser 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 authenticationmiddleware is required so that request user exists if specified header doesn t exist then remove any existing authenticated remoteuser or return leaving request user set to anonymoususer by the authenticationmiddleware 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 an authenticated user is associated with the request but it does not match the ized user in the header we are seeing this user for the first time in this session attempt to authenticate the user user is valid set request user and persist user in the session by logging the user in allow the backend to clean the username if the backend defines a cleanusername method remove the current authenticated user in the request which is invalid but only if the user is authenticated via the remoteuserbackend backend failed to load middleware for webserver provided authentication on logon pages like remoteusermiddleware but keeps the user authenticated even if the header remoteuser is not found in the request useful for setups when the external authentication via remoteuser is only expected to happen on some logon url and the rest of the application wants to use django s authentication mechanism 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 authenticationmiddleware is required so that request user exists if specified header doesn t exist then remove any existing authenticated remote user or return leaving request user set to anonymoususer by the authenticationmiddleware 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 an authenticated user is associated with the request but it does not match the ized user in the header we are seeing this user for the first time in this session attempt to authenticate the user user is valid set request user and persist user in the session by logging the user in allow the backend to clean the username if the backend defines a clean_username method backend has no clean_username method remove the current authenticated user in the request which is invalid but only if the user is authenticated via the remoteuserbackend backend failed to load middleware for web server provided authentication on logon pages like remoteusermiddleware but keeps the user authenticated even if the header remote_user is not found in the request useful for setups when the external authentication via remote_user is only expected to happen on some logon url and the rest of the application wants to use django s authentication mechanism
from functools import partial

from django.contrib import auth
from django.contrib.auth import load_backend
from django.contrib.auth.backends import RemoteUserBackend
from django.core.exceptions import ImproperlyConfigured
from django.utils.deprecation import MiddlewareMixin
from django.utils.functional import SimpleLazyObject


def get_user(request):
    if not hasattr(request, "_cached_user"):
        request._cached_user = auth.get_user(request)
    return request._cached_user


async def auser(request):
    if not hasattr(request, "_acached_user"):
        request._acached_user = await auth.aget_user(request)
    return request._acached_user


class AuthenticationMiddleware(MiddlewareMixin):
    def process_request(self, request):
        if not hasattr(request, "session"):
            raise ImproperlyConfigured(
                "The Django authentication middleware requires session "
                "middleware to be installed. Edit your MIDDLEWARE setting to "
                "insert "
                "'django.contrib.sessions.middleware.SessionMiddleware' before "
                "'django.contrib.auth.middleware.AuthenticationMiddleware'."
            )
        request.user = SimpleLazyObject(lambda: get_user(request))
        request.auser = partial(auser, request)


class RemoteUserMiddleware(MiddlewareMixin):
    

    
    
    
    header = "REMOTE_USER"
    force_logout_if_no_header = True

    def process_request(self, request):
        
        if not hasattr(request, "user"):
            raise ImproperlyConfigured(
                "The Django remote user auth middleware requires the"
                " authentication middleware to be installed.  Edit your"
                " MIDDLEWARE setting to insert"
                " 'django.contrib.auth.middleware.AuthenticationMiddleware'"
                " before the RemoteUserMiddleware class."
            )
        try:
            username = request.META[self.header]
        except KeyError:
            
            
            
            if self.force_logout_if_no_header and request.user.is_authenticated:
                self._remove_invalid_user(request)
            return
        
        
        
        if request.user.is_authenticated:
            if request.user.get_username() == self.clean_username(username, request):
                return
            else:
                
                
                self._remove_invalid_user(request)

        
        
        user = auth.authenticate(request, remote_user=username)
        if user:
            
            
            request.user = user
            auth.login(request, user)

    def clean_username(self, username, request):
        
        backend_str = request.session[auth.BACKEND_SESSION_KEY]
        backend = auth.load_backend(backend_str)
        try:
            username = backend.clean_username(username)
        except AttributeError:  
            pass
        return username

    def _remove_invalid_user(self, request):
        
        try:
            stored_backend = load_backend(
                request.session.get(auth.BACKEND_SESSION_KEY, "")
            )
        except ImportError:
            
            auth.logout(request)
        else:
            if isinstance(stored_backend, RemoteUserBackend):
                auth.logout(request)


class PersistentRemoteUserMiddleware(RemoteUserMiddleware):
    

    force_logout_if_no_header = False