Перейти к содержанию

Аутентификация и права

Все платформы экосистемы используют одну модель аутентификации. Эта страница объясняет модель и даёт практические указания для relying party (RP), которые только подключаются.

Обзор модели

sequenceDiagram
    participant U as Пользователь
    participant RP as Приложение RP
    participant SSO as Gerege SSO
    participant EID as eID Mongolia
    participant P as Телефон

    U->>RP: Нажимает «Войти»
    RP->>SSO: Authorization request (code + PKCE)
    SSO->>EID: Запуск входа по eID
    EID->>P: QR / deep-link / push
    P-->>EID: Подтверждение PIN1
    EID-->>SSO: Гражданин опознан
    SSO-->>RP: Authorization code
    RP->>SSO: code + code_verifier → токены
    SSO-->>RP: access + refresh + id_token
    RP->>SSO: /userinfo
    SSO-->>RP: Данные пользователя

Главный принцип: RP никогда не обращается к eID напрямую. Всё идёт через SSO.

Способы входа

Способ Тип Пояснение
eID Основной QR-код · мобильный deep-link · push по номеру реестра
Google Дополнительный При первом подключении обязательна проверка через eID

Чего нет: паролей, входа по email/OTP, входа по SMS OTP.

Это осознанное решение. Пароля нет — значит, он не утечёт, не будет использован повторно и не станет добычей фишинга.

Где платформа выполняет вход — AUTH_MODE

Платформа экосистемы может выступать в одной из двух ролей:

  • Служба идентификации — она аутентифицирует пользователей сама. Карточка входа (eID QR / рег. номер · Google) отображается на её главной странице и на /login.
  • Доверяющая сторона (RP) — она делегирует вход вышестоящему SSO. Нажатие «Войти» перенаправляет в SSO, пользователь входит там и возвращается.

Это не различие в коде, а конфигурация. Решает параметр backend-а AUTH_MODE:

Значение Поверхность входа
provider Карточка входа отображается на самой платформе
client Перенаправление в вышестоящий SSO (SSO_ISSUER)

Если параметр не задан, режим выводится из наличия SSO_CLIENT_ID.

Фронтенд получает режим из публичного эндпоинта GET /api/v1/site/auth — без аутентификации и без секретов в ответе:

{ "mode": "client", "sso_issuer": "https://sso.gerege.mn", "provider": false }

Быть issuer — ОТДЕЛЬНЫЙ вопрос

AUTH_MODE отвечает на вопрос «где входят пользователи этой платформы». Является ли платформа issuer-ом для других приложений, определяется отдельно параметром OAUTH_ISSUER. Оба режима могут быть активны одновременно — цепочка, когда платформа выдаёт токены другим, а своих пользователей отправляет во внешний IdP.

Практический итог: служба SSO и платформа, которая ею пользуется, работают на одном и том же коде. Один и тот же Docker-образ загружается в любой роли в зависимости от окружения. Подробнее — Общий код.

PIN1 и PIN2

PIN1 PIN2
Сертификат Authentication Signing
Назначение Вход Подпись
Юридические последствия Нет Есть — неотрекаемость

Вход ≠ подпись

Вход по PIN1 не означает, что пользователь что-либо одобрил. Для действий с юридическими последствиями (договор, выдача прав, финансовое обязательство) обязательно ставится отдельная подпись через PIN2.

Технические характеристики OIDC

Параметр Значение
Поток Authorization code + PKCE (S256)
Access token Непрозрачный
id_token JWT, RS256
Refresh token Ротируемый, с обнаружением повторного использования
Machine-to-machine client_credentials
Discovery /.well-known/openid-configuration
UserInfo /userinfo

Ротация refresh token

При каждом использовании refresh token выдаётся новый, а старый становится недействительным. Если старый токен используется повторно — это признак кражи, поэтому вся цепочка аннулируется.

Поэтому RP обязан сохранять новый токен сразу после обновления. Если оставить старый, следующее обновление обрушит все сессии.

Сессии и выход

  • Сессия — пара JWT access + refresh.
  • Выход аннулирует и refresh, и access (access deny-list).
  • После выхода пользователь возвращается на тот домен, с которого начал.

Шаги, чтобы стать RP

1. Зарегистрировать приложение

Создайте клиента в консоли Gerege SSO. Вы получите: client_id, client_secret.

Что подготовить к регистрации:

  • Redirect URI (для всех сред — dev / staging / prod)
  • Post-logout redirect URI
  • Требуемые scope
  • Название и логотип приложения (появятся на экране согласия пользователя)

2. Прочитать discovery

GET https://sso.gerege.mn/.well-known/openid-configuration

Endpoint'ы не хардкодить — читать отсюда.

3. Authorization request

Реализуйте поток authorization code + PKCE (S256). Обязательно используйте state и nonce.

4. Обменять токен

Code + code_verifieraccess_token, refresh_token, id_token.

5. Проверить id_token

Обязательно проверьте:

  • [ ] Подпись RS256 — ключом, полученным из JWKS
  • [ ] iss совпадает с issuer из discovery
  • [ ] aud равен вашему client_id
  • [ ] exp не истёк
  • [ ] nonce совпадает с отправленным вами

6. Данные пользователя

Получите их из endpoint'а /userinfo.

Частые ошибки

Redirect URI должен совпадать точно

Символ в символ: важны завершающий /, http против https, порт и подпуть. Самая частая ошибка интеграции.

Чек-лист при смене домена

При смене домена или бренда обновляйте следующие три вещи одновременно. Забудете одну — вход сломается молча:

  • [ ] Список redirect URI в SSO
  • [ ] SAN сертификата TLS
  • [ ] Адреса issuer / endpoint в конфигурации RP

PKCE нельзя пропускать

PKCE применяется даже для confidential-клиентов. Дополнительные затраты минимальны, а защита реальна.

Модель прав

После аутентификации начинается проверка прав. Стандартная иерархия экосистемы:

superadmin (1) → admin (2) → manager (3) → user (4)

Подробности — на странице Общие соглашения.

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

Для выдачи прав manager требуется подтверждение через PIN2 — подробности на странице Общие соглашения.