summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacob Walls <jacobtylerwalls@gmail.com>2026-04-30 14:53:17 -0400
committerJacob Walls <jacobtylerwalls@gmail.com>2026-05-04 13:58:50 -0400
commit0147222691db284f87c8c2a64ac6b1eded034c49 (patch)
tree6a124a9b4ff7b8142a6d95914d9a933dc994dcff
parentf8c0a9321f07c4bbb338da59d57c38878c85d1f0 (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.py10
-rw-r--r--tests/auth_tests/test_remote_user.py30
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