RemoteUserMiddleware: Make header/key and persistence settings, and deprecate PersistentRemoteUserMiddleware

Intro:

This is a suggestion for changes. If it gains traction I am interrested in making a ticket and writing a PR.

RemoteUserMiddleware is a built-in middleware that allows the webserver to externally authenticate a user and pass the authenticated username to Django using a environment variable or request header in request.META.

The key to look up from request.META is controlled by a variable called header, even if it is a environment variable by default, and does not have to be a request header. This is somewhat confusing.

PersistentRemoteUserMiddleware is a built-in subclass of RemoteUserMiddleware that will log out the user if the configured request.META key is not present on all requests. (i.e. when just doing external authentication on a /login endpoint, and handing persistence over to Django)

Suggestion #1:

  1. Make header of RemoteUserMiddleware a configurable setting, i.e. REMOTEUSER(_MIDDLEWARE)_KEY (purposefully using _KEY and not _HEADER), while keeping the default value as REMOTE_USER

Reasoning #1:

    1. Changing the key to look up in request.META is more relevant these days. The default REMOTE_USER value is the environment variable that i.e. Apache will set when authenticating a user. Anything using HTTP reverse proxying (i.e. running in a container, separate WSGI/ASGI server etc.) requires using a HTTP request header and thus changing the key.

    2. header is currently not a setting, and requires a subclass to change. This requires a sysadmin to make a subclass to change the header. I assume that more sysadmins (when integrating a Django application into the company environment) than developers will make use of RemoteUserMiddleware.

Suggestion #2:

  1. Deprecate PersistentRemoteUserMiddleware and make force_logout_if_no_header a configurabe setting on RemoteUserMiddleware, i.e. REMOTEUSER(_MIDDLEWARE)_PERSISTENT

Reasoning #2:

  1. PersistentRemoteUserMiddleware is a direct subclass of RemoteUserMiddleware with force_logout_if_no_header flipped to False. It feels messy to have a separate, built-in middleware just to change a single setting. Assuming 1. is implemented, it also makes the most sense to have this as a setting.
1 Like

Thanks for raising this here @Kag_ee! I definitely have a better understanding with it like this than I did in discord.

My personal preference would be to not make these changes. My reasoning hinges on the idea that a sysadmin should ask a developer to create a more flexible subclass of RemoteUserMiddleware for them to be able to configure it via the settings.

Is there a reason why that’s not possible for you?


The subclass I was imaging would be as follows:

class ConfigurableRemoteUserMiddleware(RemoteUserMiddleware):
    @property
    def header(self):
        return settings.CUSTOM_REMOTE_USER_AUTH_HEADER

Everything is possible. The questions is what i think Django should do by default, i.e. what batteries i think Django should include. Since we include a RemoteUserMiddleware i find it very weird that we do not have settings to control the two most common parts of it(the meta key/http header, that is very tightly bound to whatever is infront of the django server, and persistence, also tightly bound), but rather force developers to either make a extremly tiny subclass to chagne one setting (header), or use a - for some reason built in - extremely tiny subclass if they want to change the other setting (persistence).