Как выполнить аутентификацию с помощью 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) или другими ресурсоёмкими методами аутентификация на веб-сервере фронта обычно настраивается только для одной или нескольких страниц входа, а после успешной аутентификации приложение должно самостоятельно поддерживать аутентифицированную сессию.
PersistentRemoteUserMiddleware предоставляет поддержку для этого случая. Он будет поддерживать аутентифицированную сессию до явного выхода пользователя из системы. Класс может быть использован как замена RemoteUserMiddleware в документации выше.
© Django Software Foundation and individual contributors
Licensed under the BSD License.
https://docs.djangoproject.com/en/4.1/howto/auth-remote-user/