Как выполнить аутентификацию с использованием REMOTE_USER
Этот документ описывает, как использовать внешние источники аутентификации (где веб-сервер устанавливает переменную среды REMOTE_USER) в ваших приложениях Django. Такое решение аутентификации обычно используется на внутрисетевых сайтах с решениями единого входа, такими как IIS и интегрированная аутентификация Windows или Apache и mod_authnz_ldap, CAS, Cosign, WebAuth, mod_auth_sspi и т. д.
Когда веб-сервер отвечает за аутентификацию, он обычно устанавливает переменную среды REMOTE_USER для использования в прикладном уровне. В Django, REMOTE_USER доступно в атрибуте request.META. Django можно настроить для использования значения REMOTE_USER с помощью классов RemoteUserMiddleware или PersistentRemoteUserMiddleware, и RemoteUserBackend, которые находятся в django.contrib.auth.
Настройка
Сначала необходимо добавить django.contrib.auth.middleware.RemoteUserMiddleware в настройку MIDDLEWARE после django.contrib.auth.middleware.AuthenticationMiddleware:
MIDDLEWARE = [
"...",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.auth.middleware.RemoteUserMiddleware",
"...",
]
Далее, необходимо заменить ModelBackend на RemoteUserBackend в настройке AUTHENTICATION_BACKENDS:
AUTHENTICATION_BACKENDS = [
"django.contrib.auth.backends.RemoteUserBackend",
]
С такой настройкой, RemoteUserMiddleware обнаружит имя пользователя в request.META['REMOTE_USER'] и выполнит аутентификацию и автоматический вход в систему этого пользователя с использованием RemoteUserBackend.
Обратите внимание, что данная настройка отключает аутентификацию с помощью стандартного ModelBackend. Это означает, что если значение REMOTE_USER не установлено, пользователь не сможет войти в систему, даже используя интерфейс администрирования Django. Добавление 'django.contrib.auth.backends.ModelBackend' в список AUTHENTICATION_BACKENDS будет использовать ModelBackend в качестве резервного варианта, если REMOTE_USER отсутствует, что решит эти проблемы.
Управление пользователями Django, такие как представления в contrib.admin и команда управления createsuperuser, не интегрированы с удалёнными пользователями. Эти интерфейсы работают с пользователями, хранящимися в базе данных, независимо от AUTHENTICATION_BACKENDS.
Примечание
Так как RemoteUserBackend наследуется от ModelBackend, у вас по-прежнему будет вся проверка разрешений, реализованная в ModelBackend.
Пользователи с is_active=False не смогут пройти аутентификацию. Используйте AllowAllUsersRemoteUserBackend, если хотите их разрешить.
Если ваш механизм аутентификации использует пользовательский HTTP-заголовок, а не REMOTE_USER, вы можете расширить RemoteUserMiddleware и установить атрибут header на желаемый ключ request.META. Например:
from django.contrib.auth.middleware import RemoteUserMiddleware
class CustomHeaderMiddleware(RemoteUserMiddleware):
header = "HTTP_AUTHUSER"
Предупреждение
Будьте очень осторожны, если используете подкласс RemoteUserMiddleware с пользовательским HTTP-заголовком. Вы должны убедиться, что ваш фронтенд-веб-сервер всегда устанавливает или удаляет этот заголовок в зависимости от соответствующих проверок аутентификации, никогда не позволяя конечному пользователю отправлять поддельный (или «подставленный») заголовок. Поскольку HTTP-заголовки X-Auth-User и X-Auth_User (например) оба нормализуются до ключа HTTP_X_AUTH_USER в request.META, вы также должны проверить, не позволяет ли ваш веб-сервер подставленный заголовок с использованием нижних подчёркиваний вместо дефисов.
Это предупреждение не относится к RemoteUserMiddleware в его стандартной конфигурации с header = 'REMOTE_USER', так как ключ, который не начинается с HTTP_ в request.META может быть установлен только вашим сервером WSGI, а не напрямую из заголовка HTTP-запроса.
Если вам нужен больший контроль, вы можете создать собственный модуль аутентификации, который наследуется от RemoteUserBackend и переопределить один или несколько его атрибутов и методов.
Использование REMOTE_USER только на страницах входа
Модуль аутентификации RemoteUserMiddleware предполагает, что HTTP-заголовок запроса REMOTE_USER присутствует во всех аутентифицированных запросах. Это может быть ожидаемо и целесообразно при использовании Basic HTTP Auth с htpasswd или подобными механизмами, но с Negotiate (GSSAPI/Kerberos) или другими ресурсоёмкими методами аутентификации, аутентификация на фронтенд-HTTP-сервере обычно настраивается только для одной или нескольких страниц входа, а после успешной аутентификации приложение должно самостоятельно поддерживать аутентифицированную сессию.
PersistentRemoteUserMiddleware предоставляет поддержку для этого случая. Он будет поддерживать аутентифицированную сессию до явного выхода из системы пользователем. Класс может быть использован как замена RemoteUserMiddleware в документации выше.
© Django Software Foundation and individual contributors
Licensed under the BSD License.
https://docs.djangoproject.com/en/4.2/howto/auth-remote-user/