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