Вход через внешний провайдер (OIDC)
Вход через провайдера OpenID Connect — способ аутентификации, при котором клиент входит на внешний сервис идентификации, а балансировщик проверяет выданный им ID-токен. Пароль через балансировщик не проходит: его вводят на странице провайдера, а клиентский сервер получает только имя пользователя и группы.
Это единственный способ, при котором учётные записи сотрудников хранятся вне системы 5А. Выбор модуля — модуль oidc в блоке Приём учётных данных и модуль oidc в блоке Проверка.
Когда выбирают этот способ
| Ситуация | Модуль |
|---|---|
| Уже есть Keycloak, Entra ID, Okta или другой сервис идентификации | oidc — пароли сотрудников в системе 5А не хранятся |
| Приложение разбирает подписанный токен само | jwt — балансировщик проверяет подпись, но сам токен не выпускает |
| Пользователи есть только в системе 5А | basic и local_db — логины и пароли в наборе пользователей |
Между oidc и jwt разница в том, кто берёт на себя вход. При jwt балансировщик ждёт готовый токен, а кто его выдал — неважно. При oidc балансировщик сам перенаправляет клиента на страницу входа провайдера, обменивает код на токен и проверяет его у того, кто выдал.
Что нужно создать заранее
- Провайдер аутентификации типа OpenID Connect (OIDC) — в нём хранятся адреса и ключи провайдера, общие в рамках кластера.
- Профиль аутентификации с модулями oidc — в нём хранятся ID и секрет клиента, то есть то, что относится к конкретному приложению.
- Привязку профиля к сервису в конфигурации балансировки.
Набор пользователей для этого способа не нужен: пароли в системе 5А не хранятся, а проверяется подпись ID-токена.
Порядок именно такой: без провайдера поле Провайдер в профиле останется пустым, и профиль сохранить не удастся.
Как проходит вход
- Клиент обращается к опубликованному адресу сервиса без сессии.
- Балансировщик перенаправляет браузер на страницу входа провайдера, добавив адрес возврата — Путь возврата от провайдера на сервисе.
- Провайдер показывает свою форму входа и спрашивает клиента, доверять ли приложению.
- Провайдер возвращает балансировщику код, а балансировщик обменивает его на ID-токен и проверяет подпись ключами провайдера.
- Балансировщик создаёт сессию и передаёт запрос на клиентский сервер вместе с именем пользователя и группами.
Пароль не проходит по цепочке запроса и не сохраняется в балансировщике. На клиентский сервер передаётся ID-токен или, если модуль передачи header выбран, отдельные заголовки X-Auth-User и X-Auth-Groups.
Вход работает только в браузере: клиент должен выполнять перенаправление и возвращаться по адресу. Программный клиент, который не переходит по ссылкам, на страницу входа провайдера не попадёт. Для машинных интеграций нужен способ jwt — клиент сам получает токен у провайдера и присылает его заголовком.
Провайдер и клиент
Все поля, отмеченные
, являются обязательными для заполнения.
Провайдер — провайдер аутентификации, у которого балансировщик проверяет ID-токен. Под именем показывается адрес провайдера, а кнопка Открыть провайдера открывает его форму, не покидая профиль.
Один провайдер обслуживает сколько угодно профилей, поэтому секрет клиента указывается в каждом из них отдельно: у разных приложений в провайдере разные клиенты.
- ID клиента — идентификатор, под которым приложение зарегистрировано у провайдера.
- Секрет клиента — пароль приложения из регистрации у провайдера. После сохранения вместо секрета выводится «Секрет настроен. Оставьте пустым, чтобы не менять»: оставленное пустым поле сохраняет прежний секрет, а введённое — заменяет его.
Вход
Запрашиваемые scope определяют, какие сведения провайдер вернёт вместе с ID-токеном.
-
Запрашиваемые scope — состав запрашиваемых у провайдера сведений. Умолчание —
OpenID,Profile,Email. ЗначениеOpenIDобязательно: без него провайдер не выдаст ID-токен, и вход работать не будет.ProfileиEmailнужны, чтобы имя пользователя и адрес почты попали в Поле токена с пользователем и Дополнительные поля токена. Поле принимает как готовые значения, так и собственные — так запрашиваются нестандартные scope. -
Путь возврата от провайдера — служебный адрес сервиса, по которому провайдер возвращает браузер после входа. Если поле пустое, используется
/auth/oidc/callback. Адрес добавляется к адресу возврата в Valid redirect URIs у провайдера, поэтому менять его нужно вместе с настройками регистрации. -
Способ передачи секрета — как секрет клиента передаётся при обмене кода на токен: В заголовке запроса (client_secret_basic) или В теле запроса (client_secret_post). Если поле пустое, значение берётся из свойств провайдера. Значение нужно менять только если провайдер требует нестандартный способ.
-
PKCE — защита обмена кода на токен от перехвата: Включена или Выключена. Если поле пустое, значение берётся из свойств провайдера, а у провайдера без PKCE — Включена. Выключают только когда провайдер не понимает PKCE: иначе вход отвергается на этапе обмена кода.
-
Время на вход, с — сколько живёт начатый, но не завершённый вход, от
60до3600. Если поле пустое, применяется1800. По истечении срока начатый вход считается неудачным, и клиент начинает его заново. Значение стоит увеличить, если между перенаправлением на провайдера и возвратом пользователь задерживается, например из-за второго фактора или согласия на доступ.
Дополнительные параметры запроса входа дописываются к запросу авторизации как есть.
- Параметр — имя параметра запроса авторизации. Параметры протокола —
response_type,response_mode,client_id,client_secret,redirect_uri,scope,state,nonce,code_challenge,code_challenge_method,request,request_uri— задавать нельзя: они меняют способ доставки ответа, и вход перестанет работать. - Значение — значение параметра.
Типовые параметры: prompt со значением login заставляет провайдера спросить пароль заново, consent — спросить согласие на доступ, max_age — не принимать сессию провайдера старше указанного числа секунд.
Выход
Способ выхода выбирают вместе с тем, как устроены остальные приложения: уйти ли из приложения только у себя или ещё и завершить сессию во внешней системе.
- Режим выхода — Только из приложения или Из приложения и у провайдера. Если поле пустое, режим берётся из свойств провайдера: если у него объявлен эндпоинт завершения сессии, предлагается выход и у провайдера.
Режим Из приложения и у провайдера отправляет браузер на адрес завершения сессии провайдера. Это RP-Initiated Logout: сессия закрывается во всей внешней системе сразу, и войти в другое приложение, открытое в том же браузере, пользователь уже не сможет. Применим только к провайдеру, у которого в метаданных объявлен эндпоинт завершения сессии — при выборе этого режима провайдеру без такого эндпоинта вход работать не будет.
Режим Только из приложения завершает сессию балансировщика и оставляет сессию провайдера. Выбирайте его, если через того же провайдера входят в несколько приложений и закрывать их все разом не нужно.
- Путь выхода на сервисе — служебный адрес сервиса, обрабатывающий выход. Если поле пустое, используется
/auth/oidc/logout. Этот адрес используется в ссылке «Выйти» приложения: без него выйти не получится. - Куда вернуть после выхода — адрес, на который браузер попадает после выхода у провайдера. Принимается путь от корня или полный адрес
httpилиhttps. Если поле пустое, браузер возвращается на страницу «Вы вышли» балансировщика.
Путь возврата и путь выхода не должны совпадать: при совпадении профиль не сохранится. Задайте одному из профилей на одном сервисе собственные адреса.
Регистрация у провайдера
Провайдер сравнивает адреса возврата точно, без шаблонов, поэтому их нужно внести в его настройки вручную. Система 5А считает эти адреса сама и показывает их в секции Регистрация у провайдера на форме профиля — с кнопкой копирования. Секция заполняется только после первого сохранения профиля и появляется, когда профиль уже привязан хотя бы к одному сервису: адрес сервиса известен только после привязки.
Адрес возврата выводится для каждого сервиса профиля по его схеме и порту. Вместо адреса сервиса в нём стоит метка {host}: профиль не знает, по какому IP или имени открывают сервис, поэтому для каждого такого адреса регистрируется своя строка. Например, сервис на порту 8080 даёт адрес http://{host}:8080/auth/oidc/callback, а при стандартном порте он в адресе не указывается.
Адрес после выхода попадает в список Valid post logout redirect URIs только при режиме выхода Из приложения и у провайдера и заданном Куда вернуть после выхода. Путь из этого поля разворачивается в адрес для каждого сервиса; полный адрес переносится как есть.
В Keycloak до 18 версии адреса после выхода отдельное поле не проверяет. Добавьте их в Valid redirect URIs у клиента — иначе после выхода провайдер отвергнет адрес и вернёт клиента на страницу ошибки.
Проверка ID-токена
Модуль проверки oidc сверяет ID-токен с тем провайдером, который его выдал, и достаёт из него личность клиента.
- Поле токена с пользователем — поле ID-токена, значение которого становится именем клиента. Если поле пустое, используется
sub.sub— неизменяемый идентификатор: используйте его, если приложению нужен постоянный идентификатор пользователя.preferred_usernameподходит для читаемого логина, но провайдер может его изменить;emailпостоянным идентификатором не является. - Поле токена с группами — поле ID-токена со списком групп, по которому работают разрешённые группы в привязке. Если поле пустое, используется
groups. Значение может быть и списком, и одной строкой через пробел или запятую.
В Keycloak роли лежат во вложенных полях, а не в groups. Задайте путь с точками: realm_access.roles для ролей области, resource_access.com\.example\.client.roles для ролей клиента. Точку внутри уровня экранируйте обратной косой чертой — экранирование нужно, когда идентификатор клиента сам содержит точки.
Если группы из ID-токена не попадают в Разрешенные группы привязки, клиент с верным паролем всё равно получит отказ. Проверьте, что путь к группам совпадает с тем, что провайдер кладёт в токен, и что у клиента запрошены scope, дающие эти группы.
Дополнительные поля токена — соответствия «атрибут → поле ID-токена», которыми балансировщик наполняет атрибуты личности.
- Атрибут — имя атрибута личности. Оно должно совпадать с именем атрибута в идентификационных заголовках на вкладке Дополнительно профиля.
- Поле ID-токена — поле ID-токена, значение которого попадёт в атрибут.
У нового профиля заданы два соответствия: username берётся из preferred_username и передаётся в заголовке X-Auth-Username, email берётся из email и передаётся в заголовке X-Auth-Email. Привяжите к ним те поля, которые читает приложение, и при необходимости измените заголовки на вкладке Дополнительно.
Порядок настройки
- Уточните у администратора сервиса идентификации Адрес провайдера (issuer) и создайте провайдера аутентификации. Нажмите Получить сведения — из метаданных подставятся адреса эндпоинтов, адрес набора ключей JWKS и поддерживаемые свойства провайдера.
- Создайте профиль аутентификации. В блоке Приём учётных данных добавьте модуль oidc, в блоке Проверка — модуль oidc.
- Укажите Провайдер, ID клиента и Секрет клиента.
- Оставьте Запрашиваемые scope и Путь возврата от провайдера как есть: они соответствуют адресам по умолчанию.
- Сохраните профиль и привяжите его к сервису — см. Аутентификация и авторизация сервиса.
- В секции Регистрация у провайдера скопируйте адреса и передайте их администратору сервиса идентификации для регистрации клиента.
- Выберите режим выхода и, если нужен выход у провайдера, задайте Куда вернуть после выхода, затем добавьте адрес после выхода в регистрацию клиента.
- В блоке Передача на бэкенд добавьте модуль header, чтобы приложение получило имя пользователя и группы.
- На вкладке Сессии оставьте включённые сессии: без них браузер не узнаётся на следующем запросе, и вход придётся проходить каждый раз.
Пример: Keycloak
Задача: сотрудники входят в корпоративный портал через Keycloak. Пароли в системе 5А не хранятся, портал получает имя пользователя и группы в заголовках.
- Создайте в Keycloak клиент с типом Confidential, включите стандартный поток и Direct Access Grants.
- В Valid redirect URIs клиента добавьте адрес возврата из секции Регистрация у провайдера — например,
https://portal.example.ru/auth/oidc/callback. - Создайте провайдера с адресом
https://sso.example.ru/realms/employeesи нажмите Получить сведения. - Скопируйте из Keycloak ID клиента и Секрет клиента в профиль.
- В профиле задайте Поле токена с группами —
realm_access.roles, а Поле токена с пользователем —preferred_username. - В блоке Передача на бэкенд выберите header. На вкладке Дополнительно соответствия
username→X-Auth-Usernameиemail→X-Auth-Emailсоздаются автоматически; измените их, если портал ожидает другие заголовки. - В привязке укажите Разрешенные группы — те же имена, что и роли в Keycloak.
Портал получает X-Auth-User со значением preferred_username и X-Auth-Groups со списком ролей области.
Пример: один вход на два приложения
Задача: два сервиса в разных кластерах используют один Keycloak, но выход из одного не должен закрывать второй.
Создайте два профиля с одним и тем же провайдером: у каждого клиента в Keycloak свои ID клиента и Секрет клиента. В каждом профиле укажите свой Путь возврата от провайдера и свой Путь выхода на сервисе — иначе адреса на разных сервисах совпадут, и профили не сохранятся. Режим выхода оставьте Только из приложения, а Куда вернуть после выхода задайте путь на свой сервис.
Проверка
- Откройте защищённый путь в браузере — ожидается переход на страницу входа провайдера, а не отказ балансировщика.
- Войдите под учётной записью, которой разрешён доступ, — ожидается страница приложения.
- Посмотрите заголовки запроса, переданного на клиентский сервер: в них должны быть
X-Auth-UserиX-Auth-Groups. - Нажмите выход в приложении и повторите запрос — ожидается возврат на страницу входа провайдера.
Если браузер возвращает ошибку с адреса провайдера, сверьтесь с журналом: чаще всего это несовпадение адреса возврата с зарегистрированным у клиента. Если провайдер пишет, что клиент неизвестен, проверьте ID клиента и Секрет клиента.
Проверяйте на опубликованном адресе, а не на клиентском сервере: запрос без входа на бэкенд не передаётся, и проверка на самом сервере ничего не покажет.