Авторизация с использованием 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/2.2/howto/auth-remote-user/