Перейти к содержимому

Как развернуть единый вход (SSO)

Инструкция для того, кто разворачивает Zentro у заказчика, и администратора Zentro: как сделать, чтобы приложения организации входили через Zentro — один вход на все приложения, общий экран входа, согласие и выход.

Установка фронта — Установка панели и кабинета, подключение приложений — Подключение сервиса (сервис целиком) и Подключение приложения (отдельное приложение).

Zentro Identity — провайдер входа (OpenID Connect). Своего экрана у него нет: вход, второй фактор и «Разрешить» пользователь видит в личном кабинете Zentro.

Приложение ──(1) «Войти»──▶ Identity /oidc/authorize
│ (2) нет входа или нужно согласие
▼
Личный кабинет /oidc/consent
вход · второй фактор · «Разрешить»
│ (3) код
▼
Приложение ◀────────────── redirect_uri?code=…
│ (4) сервер приложения меняет код на токены в Identity
  • Один вход на все приложения: вошли в кабинет один раз — остальные приложения пускают без пароля, пока жива сессия кабинета.
  • Кабинет публикуется наружу, панель — нет. В кабинете нет админского кода вообще, его BFF не пропускает запросы к админскому API. Панель остаётся во внутренней сети.
  • У панели своя сессия. Панель — не SSO-приложение, в неё входят отдельно.
  • Домены с TLS (пример по тексту):

    Адрес Что там Снаружи
    https://id.example.com Identity да — к нему ходят браузеры и приложения
    https://account.example.com личный кабинет да — здесь входят пользователи
    https://admin.example.com панель нет, только внутренняя сеть или VPN
  • Identity установлен (Установка сервера), первый администратор заведён, у него есть второй фактор.

  • Фронт установлен (Установка панели и кабинета).

  • Почта (SMTP) у Identity — без неё не уйдут ссылки на сброс пароля, подтверждение почты и привязки.

Это переменные окружения Identity — их задаёт тот, кто его разворачивает (identity.env, .env compose). После правки Identity перезапускают. Что выбрать и почему (адреса, подпись токенов, секреты) — Выбор настроек.

Переменная Значение Зачем
PUBLIC_BASE_URL https://id.example.com Адрес Identity — он же issuer в токенах. Приложения проверяют его в каждом токене; менять после запуска нельзя без перенастройки всех приложений
OIDC_AUTHORIZE_UI_URL https://account.example.com/oidc/consent Куда Identity отправляет пользователя войти и дать согласие. Не задан — вход в приложения обрывается на пустой странице
PASSWORD_RESET_URL https://account.example.com/reset-password Ссылка в письме сброса пароля
EMAIL_VERIFY_URL https://account.example.com/verify-email Ссылка подтверждения почты
EMAIL_CHANGE_URL https://account.example.com/confirm-email-change Ссылка подтверждения новой почты
WEBAUTHN_RP_ID example.com Домен ключей (passkey): общий родитель адресов кабинета и панели
WEBAUTHN_RP_ORIGIN https://account.example.com,https://admin.example.com Оба адреса фронта через запятую. Адреса нет в списке — ключи на нём не работают
TRUSTED_PROXY_CIDRS адрес прокси перед Identity Иначе в сессиях, аудите и лимитах будет адрес прокси, а не пользователя
SMTP_* почтовый сервер Письма пользователям

Проверка: https://id.example.com/.well-known/openid-configuration открывается из браузера, issuer в нём — ровно PUBLIC_BASE_URL.

Настройки в панели — то, что меняется без перезапуска (кроме CORS):

Настройка По умолчанию Когда менять
oidc.authorize_request_ttl 30 минут Сколько у пользователя времени от «Войти» в приложении до «Разрешить»: войти, завести второй фактор, восстановить пароль. Истекло — приложение начинает вход заново
oidc.end_session_scope current current — выход из приложения завершает только его сессию; sso — выход на этом устройстве: вход в Zentro, из которого открыто приложение, и все приложения под ним; all — выход везде: все сессии пользователя и уведомление остальным приложениям
oidc.backchannel_private_cidrs пусто Внутренние сети (10.20.0.0/16), куда Identity может слать уведомления о выходе приложениям без публичного адреса
cors.enabled, cors.allowed_origins выкл. Только если есть приложения целиком в браузере (SPA без сервера): их адреса. Применяется после перезапуска Identity
security.* — Политика паролей, второго фактора и порог для особых операций — по требованиям заказчика

Каждое приложение регистрируется в Identity:

Команде приложения уходит сводка с issuer и Discovery — дальше приложение берёт все адреса оттуда.

Согласие. При первом входе в приложение пользователь видит «Разрешить» с названием приложения и тем, что оно получит. Для своих приложений организации экран можно убрать — «Приложение организации — не спрашивать согласие» у приложения. Стороннему не убирайте: согласие защищает пользователя. Выданные согласия пользователь видит и отзывает в кабинете (Приложения с доступом).

Повторный вход и уровень входа — приложение может потребовать:

Приложение передаёт Что увидит пользователь
prompt=login Экран входа, даже если он уже вошёл (с подсказкой, зачем)
max_age=N То же, если вход был дольше N секунд назад
acr_values=AAL2 / AAL3 Подтверждение вторым фактором / ключом, если текущий вход слабее
prompt=none Ничего: вошёл — сразу код, нет — ошибка приложению без экрана

Если у заказчика свой каталог (Keycloak, корпоративный OIDC, LDAP, Active Directory), его подключают как внешний провайдер входа (Внешние IdP) — пользователи входят в кабинет и приложения корпоративным логином.

  • LDAP / AD (вход по паролю через форму Zentro) — работает и в кабинете, и в панели.

  • OIDC / Keycloak (переход на страницу провайдера) — работает в кабинете и в панели. Нужно:

    • у фронта — публичные адреса BFF: ACCOUNT_PUBLIC_URL=https://account.example.com/bff, PORTAL_PUBLIC_URL=https://admin.example.com/bff (Установка панели и кабинета, шаг 2);

    • в провайдере и в Zentro (Внешние IdP → Redirect URI) — оба адреса возврата:

      https://account.example.com/bff/auth/idp/<имя провайдера>/callback
      https://admin.example.com/bff/auth/idp/<имя провайдера>/callback

    Человек вернётся в то приложение, где начал вход. Не заданы публичные адреса — Identity вернёт на первый адрес списка (поставьте первым кабинет).

    Привязка аккаунта через такой провайдер, начатая в панели, пока возвращает в кабинет — привязывайте в кабинете (вопрос к бэку открыт).

Подробно о провайдерах — Внешние провайдеры входа.

  1. https://id.example.com/.well-known/openid-configuration — issuer = PUBLIC_BASE_URL.
  2. Кабинет https://account.example.com открывается, вход работает, письмо «Забыли пароль?» приходит и ссылка из него открывает кабинет.
  3. Ключ (passkey): завести в кабинете (Безопасность) и войти им — работает и в кабинете, и в панели.
  4. Тестовое приложение: «Войти» → экран входа кабинета → «Разрешить» → вернулись в приложение.
  5. Второе приложение: «Войти» — без пароля, сразу обратно (или только «Разрешить»).
  6. Выход из приложения; при oidc.end_session_scope=sso — вышли и из остальных приложений на этом устройстве, при all — везде.
  7. Панель снаружи не открывается.
Что видно Причина Что сделать
«Войти» в приложении → пустая страница или ошибка Identity Не задан OIDC_AUTHORIZE_UI_URL или указывает не на кабинет Шаг 1
Приложение отвергает токен: неверный iss PUBLIC_BASE_URL не совпадает с тем, что знает приложение (http/https, слэш, порт) Приложение берёт issuer из Discovery; PUBLIC_BASE_URL — ровно публичный адрес
Ключ (passkey) не работает на одном из адресов Адреса нет в WEBAUTHN_RP_ORIGIN или WEBAUTHN_RP_ID не родитель домена Шаг 1
Ссылки из писем ведут не туда PASSWORD_RESET_URL / EMAIL_*_URL указывают на старый адрес Шаг 1
Письма не приходят Нет SMTP у Identity SMTP_*; проверить журнал Identity
«Запрос на вход устарел. Вернитесь в приложение и войдите снова» Пользователь не уложился в oidc.authorize_request_ttl Начать вход в приложении заново; при необходимости увеличить срок
Все пользователи упираются в «слишком много попыток» Identity или фронт видят адрес прокси вместо адресов пользователей TRUSTED_PROXY_CIDRS у Identity; для фронта — REAL_IP_FROM (Установка панели и кабинета, шаг 5)
SPA-приложение не может получить токен (ошибка CORS в браузере) Адрес приложения не разрешён в CORS Identity cors.enabled, cors.allowed_origins, перезапуск Identity
Корпоративный вход в панели уводит в кабинет Не задан PORTAL_PUBLIC_URL — Identity вернул на первый адрес Задать публичные адреса BFF и добавить адрес панели в Redirect URI
«Вход через этого провайдера здесь не настроен» Адреса возврата этого приложения нет в Redirect URI провайдера в Zentro Добавить …/bff/auth/idp/<имя>/callback этого приложения