Вход в систему¶
Модуль CM Ocean Loyalty не имеет собственной формы входа. Аутентификация выполняется
централизованно — через корпоративный сервер идентификации Keycloak по протоколам
OAuth2 / OpenID Connect (OIDC), а пользователь работает с модулем в составе единого
окна-хоста Core UI. Доступ к функциям разграничивается ролями LOYALTY_*, которые
приходят в токене доступа (JWT) из Keycloak.
Единый вход в составе Core UI¶
Интерфейс лояльности (разделы «Акции», «Клиенты», «Администрирование» и другие — см. «Единое окно и навигация») встроен в Core UI как микрофронтенд. Это означает:
- Пользователь авторизуется один раз — на стороне Core UI / Keycloak (поток Authorization Code). Отдельный логин для модуля лояльности не требуется.
- Открыв вкладки лояльности, пользователь уже находится в авторизованной сессии; токен доступа автоматически передаётся в запросы к API модуля.
Интерактивный и сервисный доступ
Интерактивный клиент (UI-пользователь) использует поток Authorization Code через
клиент frontend. Сервисные и не-UI вызовы (интеграции, фоновые задачи) используют
отдельный клиент с потоком Client Credentials — набор прав при этом тот же.
Как устроена аутентификация на бэкенде¶
Бэкенд loyalty-billing сконфигурирован как stateless OAuth2 resource server: он не
хранит пользовательских сессий и на каждый запрос проверяет JWT, выпущенный Keycloak.
Принципы:
- Deny-by-default. Любой запрос к бизнес-API требует валидного токена; всё, что не разрешено явно, отклоняется.
- Без сессий и без CSRF-куки. Сессии не создаются (
SessionCreationPolicy.STATELESS), защита CSRF отключена как ненужная для stateless-API. - Издатель токена (issuer). Доверенный издатель JWT задаётся через переменную окружения
(
spring.security.oauth2.resourceserver.jwt.issuer-uri) и указывает на realm Keycloak. - CORS. Кросс-доменные обращения по умолчанию запрещены; разрешённые источники
(например, домен Core UI) задаются переменной окружения
LOYALTY_CORS_ALLOWED_ORIGINS.
Публичные адреса (без аутентификации)¶
Без токена доступны только служебные эндпоинты эксплуатации и документация API — никаких бизнес-данных они не отдают:
| Назначение | Путь |
|---|---|
| Проба здоровья (k8s liveness/readiness) | /health, /health/** |
| Метрики Prometheus | /metrics |
| Служебная информация | /info |
| Спецификация OpenAPI | /v3/api-docs, /v3/api-docs/** |
| Swagger UI | /swagger-ui/**, /swagger-ui.html |
Note
Служебные эндпоинты публикуются на отдельном management-порту и не относятся к
бизнес-API /v1. Все прикладные операции лояльности всегда требуют аутентификации.
Роли LOYALTY_*¶
Роли пользователя берутся из токена — из клейма resource_access соответствующего клиента
Keycloak — и имеют префикс продукта LOYALTY_. На каждой прикладной операции бэкенд
проверяет нужную роль (@PreAuthorize). Назначение ролей пользователям выполняется
администратором в Keycloak.
Основные роли и что они открывают (полный перечень и составные правила — в разделе «Ролевая модель»):
| Роль | Что разрешает |
|---|---|
LOYALTY_CUSTOMER_READ / LOYALTY_CUSTOMER_WRITE |
Просмотр и создание карточек клиентов; правка профиля, блокировка, архивирование, слияние, импорт клиентов |
LOYALTY_PROFILE_READ |
Просмотр профиля клиента (идентичность MDM + данные лояльности); также staff-предпросмотр B2C-кабинета |
LOYALTY_TAG_READ / LOYALTY_TAG_WRITE |
Справочник тегов клиента (свой экран, не открывается общими правами на справочники) |
LOYALTY_CUSTOMER_TAG_WRITE |
Присвоение и снятие тегов клиенту (отдельно от справочника и от LOYALTY_CUSTOMER_WRITE), в том числе по списку на экране «Ручные операции» |
LOYALTY_ACCOUNT_READ / LOYALTY_ACCOUNT_WRITE |
Счета и баланс баллов (доступно / в резерве); создание счетов |
LOYALTY_ACCRUAL_WRITE / LOYALTY_REDEMPTION_WRITE / LOYALTY_TIER_WRITE / LOYALTY_CUSTOMER_TAG_WRITE |
Экран «Ручные операции» открывается по любой из четырёх ролей; доступны только те операции (начисление, корректировка, перевод уровня, добавление и снятие тегов), на которые есть право |
LOYALTY_OPERATION_REASON_OTHER_WRITE |
Причина «Прочее» у ручной операции с баллами или уровнем — сверх права на саму операцию |
LOYALTY_OPERATION_WRITE |
Операции леджера: пополнение, списание, перевод, обмен |
LOYALTY_PROMOTION_READ / LOYALTY_PROMOTION_WRITE |
Каталог механик и акции: просмотр, создание, изменение, пауза, архивирование, версии, статистика, экспорт-импорт, отправка на согласование |
LOYALTY_PROMOTION_ACTIVATE |
Запуск акции — одиночный и массовый; право записи запуска не даёт |
LOYALTY_PROMOTION_APPROVE |
Согласование и отклонение запуска акции (принцип «четырёх глаз») |
LOYALTY_PROMOTION_LABEL_READ / LOYALTY_PROMOTION_LABEL_WRITE |
Справочник меток акций (свой экран) |
LOYALTY_ACHIEVEMENT_READ / LOYALTY_ACHIEVEMENT_WRITE |
Каталог правил достижений «условие — бейдж» и пересчёт бейджей клиента |
LOYALTY_EVENT_WRITE |
Регистрация покупки (покупка → акция → начисление) |
LOYALTY_PROGRAM_CONFIG_READ / LOYALTY_PROGRAM_CONFIG_WRITE |
Раздел «Конфигурации программы»: просмотр каталога и истории активаций; создание, правка черновика, дублирование, удаление |
LOYALTY_PROGRAM_CONFIG_ACTIVATE |
Активация конфигурации программы — отдельно от права правки |
LOYALTY_TIER_READ / LOYALTY_TIER_WRITE |
Уровни и уровень клиента с прогрессом; ручное назначение уровня, параметры уровня |
LOYALTY_BUSINESS_DAY_WRITE |
Закрытие бизнес-дня |
LOYALTY_MONITORING_READ |
Мониторинг и раздел «Отчёты»: сводки, аномалии, скоро сгорающие баллы, бизнес-день, отчёты за период, сквозной журнал аудита, сверка итогов |
LOYALTY_MAINTENANCE_WRITE |
Сервисные операции (сгорание просроченных баллов, предупреждения о сгорании, запуск сверки итогов) |
LOYALTY_INTAKE_READ / LOYALTY_INTAKE_WRITE |
Очередь приёма: разбор отложенных команд, возврат в работу, отмена |
LOYALTY_EXCHANGE_READ / LOYALTY_EXCHANGE_WRITE |
Обмен данными с внешними системами: ленты изменений, регламент и ручной запуск |
LOYALTY_INTEGRATION_READ / LOYALTY_INTEGRATION_WRITE |
Интеграции: резолюция карты на POS, обзор для Check Scan — чтение; приём чеков POS, начислений Promo/RT Flow — запись |
LOYALTY_DICTIONARY_READ / LOYALTY_DICTIONARY_WRITE |
Справочники общего реестра, справочник валют и пары обмена, субсчета, настройка профиля клиента, «Настройка акции», ограничения на списание, глобальная механика: просмотр и правка (у справочников — только локальных редактируемых) |
LOYALTY_CLIENT_PROFILE_ACTIVATE / LOYALTY_CLIENT_PROFILE_DELETE |
Активация и удаление версий настройки карточки клиента — отдельно от права правки |
LOYALTY_SEGMENT_READ / LOYALTY_SEGMENT_WRITE |
Экран «Сегменты клиентов»: список сегментов и журнал заливок; архивация, возврат из архива, удаление |
LOYALTY_CITY_*, LOYALTY_STORE_*, LOYALTY_MERCHANT_*, LOYALTY_PRODUCT_CATALOG_* |
Справочники городов, торговых точек, мерчантов, категорий товаров и артикулов (у каждого своя пара _READ / _WRITE) |
Принцип наименьших привилегий
Роли независимы и аддитивны: пользователю назначают ровно тот набор, который нужен его
задачам. Например, оператору мониторинга достаточно LOYALTY_MONITORING_READ, маркетологу для
подготовки акций — LOYALTY_PROMOTION_READ и LOYALTY_PROMOTION_WRITE, а для их запуска —
ещё LOYALTY_PROMOTION_ACTIVATE.
Что происходит без нужной роли¶
Возможны два исхода:
- Нет действующей сессии / токена — запрос к API отклоняется как неаутентифицированный (HTTP 401 Unauthorized). На практике пользователь Core UI этого не видит: вход уже выполнен в едином окне.
- Токен есть, но нужной роли
LOYALTY_*нет — операция отклоняется как запрещённая (HTTP 403 Forbidden). В интерфейсе это проявляется как экран «Нет доступа к разделу» с перечнем недостающих ролей или как недоступность соответствующего действия.
sequenceDiagram
participant U as Пользователь (Core UI)
participant KC as Keycloak
participant API as loyalty-billing
U->>KC: Вход (Authorization Code)
KC-->>U: Токен доступа (JWT) с ролями LOYALTY_*
U->>API: Запрос с JWT (например, GET /v1/promotions)
API->>API: Проверка подписи и издателя токена
alt Токен отсутствует/недействителен
API-->>U: 401 Unauthorized
else Нет нужной роли
API-->>U: 403 Forbidden
else Роль есть
API-->>U: 200 OK + данные
end
Если раздел недоступен или операция возвращает 403
Это, как правило, означает отсутствие нужной роли LOYALTY_*, а не сбой системы.
Обратитесь к администратору платформы для назначения соответствующей роли в Keycloak.
Гейтинг прав в UI (с 26.0.0)
С выпуска 26.0.0 интерфейс заранее отражает права: кнопки изменяющих действий
(создание, редактирование, слияние, назначение уровня, импорт акций и т. п.) неактивны
без соответствующей роли LOYALTY_*_WRITE, а на кнопке показывается тултип с требуемой ролью.
Это лишь подсказка для оператора — итоговая проверка прав всё равно выполняется на бэкенде
(403 при отсутствии роли).