diff options
| author | Jacob Walls <jacobtylerwalls@gmail.com> | 2026-04-30 14:53:17 -0400 |
|---|---|---|
| committer | Jacob Walls <jacobtylerwalls@gmail.com> | 2026-05-04 13:58:50 -0400 |
| commit | 0147222691db284f87c8c2a64ac6b1eded034c49 (patch) | |
| tree | 6a124a9b4ff7b8142a6d95914d9a933dc994dcff | |
| parent | f8c0a9321f07c4bbb338da59d57c38878c85d1f0 (diff) | |
Fixed #37079 -- Fixed specialization of header lookups in RemoteUserMiddleware.
We need to switch on whether the request is a WSGI or ASGI request to
know whether to prepend `HTTP_`: we cannot assume sync exceution means
we are running under WSGI, as there could be other sync middleware
forcing sync execution under ASGI.
Thanks Mykhailo Havelia for the report.
| -rw-r--r-- | django/contrib/auth/middleware.py | 10 | ||||
| -rw-r--r-- | tests/auth_tests/test_remote_user.py | 30 |
2 files changed, 38 insertions, 2 deletions
diff --git a/django/contrib/auth/middleware.py b/django/contrib/auth/middleware.py index bedb749d92..c38cd8bc99 100644 --- a/django/contrib/auth/middleware.py +++ b/django/contrib/auth/middleware.py @@ -8,6 +8,7 @@ from django.contrib.auth import REDIRECT_FIELD_NAME, load_backend from django.contrib.auth.backends import RemoteUserBackend from django.contrib.auth.views import redirect_to_login from django.core.exceptions import ImproperlyConfigured +from django.core.handlers.asgi import ASGIRequest from django.shortcuts import resolve_url from django.utils.deprecation import MiddlewareMixin from django.utils.functional import SimpleLazyObject @@ -141,7 +142,7 @@ class RemoteUserMiddleware: f" before the {self.__class__.__name__} class." ) try: - username = request.META[self.header] + username = self._get_username(request) except KeyError: # If specified header doesn't exist then remove any existing # authenticated remote-user, or return (leaving request.user set to @@ -183,7 +184,7 @@ class RemoteUserMiddleware: f" before the {self.__class__.__name__} class." ) try: - username = request.META["HTTP_" + self.header] + username = self._get_username(request) except KeyError: # If specified header doesn't exist then remove any existing # authenticated remote-user, or return (leaving request.user set to @@ -236,6 +237,11 @@ class RemoteUserMiddleware: pass return username + def _get_username(self, request): + if isinstance(request, ASGIRequest): + return request.META["HTTP_" + self.header] + return request.META[self.header] + def _remove_invalid_user(self, request): """ Remove the current authenticated user in the request which is invalid diff --git a/tests/auth_tests/test_remote_user.py b/tests/auth_tests/test_remote_user.py index f88d966bad..8c85c65196 100644 --- a/tests/auth_tests/test_remote_user.py +++ b/tests/auth_tests/test_remote_user.py @@ -1,5 +1,7 @@ from datetime import UTC, datetime +import asgiref.sync + from django.conf import settings from django.contrib.auth import aauthenticate, authenticate from django.contrib.auth.backends import RemoteUserBackend @@ -14,6 +16,15 @@ from django.test import ( modify_settings, override_settings, ) +from django.utils.decorators import sync_only_middleware + + +@sync_only_middleware +def sync_middleware(get_response): + def middleware(request): + return get_response(request) + + return middleware @override_settings(ROOT_URLCONF="auth_tests.urls") @@ -470,6 +481,20 @@ class RemoteUserCustomTest(RemoteUserTest): self.assertEqual(newuser.email, "user@example.com") +class ASGISyncPathRemoteUserTest(RemoteUserTest): + """Later sync-only middleware forces sync execution even under ASGI.""" + + middleware = [ + RemoteUserTest.middleware, + "auth_tests.test_remote_user.sync_middleware", + ] + + def setUp(self): + method = getattr(self, self._testMethodName) + if not isinstance(method, asgiref.sync.AsyncToSync): + self.skipTest("This test covers async-only functionality") + + class CustomHeaderMiddleware(RemoteUserMiddleware): """ Middleware that overrides custom HTTP auth user header. @@ -488,6 +513,11 @@ class CustomHeaderRemoteUserTest(RemoteUserTest): header = "HTTP_AUTHUSER" +class CustomHeaderASGISyncPathRemoteUserTest(ASGISyncPathRemoteUserTest): + middleware = "auth_tests.test_remote_user.CustomHeaderMiddleware" + header = "HTTP_AUTHUSER" + + class PersistentRemoteUserTest(RemoteUserTest): """ PersistentRemoteUserMiddleware keeps the user logged in even if the |
