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

# Интеграция с IdP-провайдером

Система BAF позволяет настроить интеграцию с провайдером IdP по протоколу OIDC для организации аутентификации и авторизации через внешний источник пользователей.

При этом сама система не хранит данные таких внешних пользователей — вся информация о пользователе передается в ходе выполнения потока OIDC, и в результате формируется cookie с коротким сроком действия для взаимодействия с панелью управления BAF. На текущий момент поддерживается только режим работы `Authorization Code`.

Кроме того, система полагается на IdP-провайдера в части сопоставления ролей, пользователей и рабочих пространств. Сами роли и их привилегии создаются внутри BAF, но связь «роль — пользователь — рабочее пространство» должна быть задана на стороне IdP.

Таким образом, задача интегратора состоит в корректном переносе и поддержании в согласованном состоянии рабочих пространств и ролей между IdP и BAF. Предполагается, что создание новых учетных записей и ролей происходит редко, поэтому синхронизация выполняется нечасто.

примечание

Узнать подробнее о ролевой модели

Если вам не требуется интеграция с IdP, пропустите его настройку и оставьте стандартные значения поставки.

## Подготовка IdP​

Перед настройкой BAF необходимо подготовить IdP. Рассмотрим процесс на примере Keycloak.

### Создание realm​

Для управления пользователями BAF рекомендуем создать отдельный `realm`, чтобы интеграция с BAF не пересекались с другими интеграциями.

### Создание клиента​

После создания отдельного `realm` необходимо создать `client`, который будет использоваться BAF для взаимодействия с Keycloak.

Тип клиента должен быть OpenID Connect, также необходимо выбрать client-id. В примере возьмем `baf-client`.

BAF считается конфиденциальным клиентом, поэтому необходимо включить аутентификацию. Остальные переключатели оставьте так, как показано на скриншоте.

Далее необходимо настроить проверку URL-адресов перенаправления. Для примера предположим, что BAF развернут по адресу `https://127.0.0.1:8090`. Рекомендуемая настройка URL показана ниже:

примечание

Ваш домен системы может отличаться, однако путь перенаправления всегда соответствует `/signin-idp/*`, поскольку этот путь зашит внутри BAF.

В результате этих операций появится новый клиент, через который BAF будет взаимодействовать с Keycloak.

### Сопоставление ролей​

Задача привязки ролей и учетных записей к пользователям лежит на стороне IdP-провайдера. Необходимо выстроить удобную для вас систему, позволяющую добавлять пользователям IdP информацию о ролях и рабочих пространствах для последующей трансформации в claims токена и разбора внутри BAF.

Система BAF должна однозначно понимать, какого типа роль, к какой учетной записи она привязана, и какому пользователю принадлежит.

Для этого система разбирает утверждения, полученные при аутентификации пользователя в IdP, формирует из них набор ролей и сохраняет всю информацию в cookie с коротким сроком действия, которая затем используется BAF для аутентификации и авторизации пользователя.

Мы рассматриваем систему ролей на основе атрибутов пользователя Keycloak, однако вы можете использовать любой другой способ формирования утверждений, который вам покажется удобным.

В данной системе у каждого пользователя внутри `realm` появляется набор атрибутов. Каждый атрибут означает наличие или отсутствие роли: для глобальных ролей — просто факт наличия, а для локальных — в каком рабочем пространстве эта роль действует.

примечание

Роли имеют уникальное имя и споставление происходит по нему.

### Атрибуты пользователей​

Для начала создадим атрибут для стандартной глобальной роли `SuperAdmin`. Любая другая созданная вами роль, которая должна работать в глобальном контексте, настраивается аналогично.

Перейдите на страницу Realm Settings, вкладку User Profile и нажмите кнопку Create Attribute.

Откроется страница создания атрибута. В основном вы можете настроить атрибут по своему усмотрению. Имя атрибута здесь играет только визуальную роль и на сопоставление не влияет. Самое важное — корректно настроить Validators и Annotations.

- В Validators выберите тип `options` с двумя значениями: `true` и `false`.
- В Annotations выберите аннотацию `select-radiobuttons`.

В результате у каждого пользователя `realm` появится атрибут, означающий наличие или отсутствие глобальной роли `SuperAdmin`.

примечание

Чтобы настроить локальные роли, необходимо получить список существующих рабочих пространств. Удобнее всего это сделать через страницу рабочих пространств, которая доступна пользователям с ролью `SuperAdmin`. Рекомендуется сначала настроить сопоставления для роли `SuperAdmin` и назначить ее соответствующему пользователю, а затем вернуться к данному разделу и настроить локальные роли.

Далее настроим атрибут для локальной роли, например, `ApplicantReader`. Снова нажмите Create Attribute.

На странице настройки атрибута также важно настроить Validators и Annotations, остальное — на ваше усмотрение.

- В Validators выберите два типа: `multivalued` (для возможности выбора нескольких значений) и `options` со значениями идентификаторов рабочих пространств (их можно скопировать на странице рабочих пространств, открыв ее пользователем с ролью `SuperAdmin`).
- В Annotations выберите аннотацию `multivalue`.

примечание

При добавлении нового рабочего пространства необходимо актуализировать `options` у всех атрибутов локальных ролей.

В результате у каждого пользователя `realm` появится атрибут, означающий наличие роли `ApplicantReader` в тех или иных рабочих пространствах.

### Сопоставление claims​

Создав атрибуты, вы обеспечили возможность настраивать роли у пользователей, но BAF все еще не будет их видеть. Для отображения пользовательских атрибутов необходимо настроить их сопоставление с claims.

Для этого перейдите во вкладку Client Scopes в ранее созданном клиенте и выберите область с описанием «Dedicated scope and mappers for this client».

Добавьте сопоставители для новых атрибутов. Начнем с глобальной роли `SuperAdmin`.

Нажмите Add Mapper → By Configuration и в открывшемся списке выберите User Attribute.

Настройте атрибут:

- User Attribute — выберите из списка ранее созданный атрибут `SuperAdmin`.
- Token Claim Name — задайте формат ключа для claim. Важно запомнить этот формат, так как он будет участвовать в логике разбора данных роли на стороне BAF. Для примера используем `grole-<имя роли внутри <ShortProductName/>>`, т.е. `grole-SuperAdmin`.
- Claim JSON Type — выберите `string`.
- Add to ID token, Add to access token, Add to userinfo, Add to token introspection — оставьте включенными.

В результате будет сформировано утверждение с ключом `grole-SuperAdmin` и значением `true` или `false`.

Теперь настроим сопоставитель для локальной роли `ApplicantReader`. Конфигурация аналогична, за исключением включенного поля `Multivalued` и другого шаблона ключа утверждения (поле Token Claim Name): `role-<имя роли внутри <ShortProductName/>>`, т.е. `role-ApplicantReader`.

В результате будет сформировано утверждение с ключом `role-ApplicantReader` и значением UUID рабочего пространства. Если рабочих пространств несколько, будет создано несколько claims с одинаковыми ключами и соответствующими значениями UUID.

примечание

Важно понимать, в каком формате утверждения передаются в систему BAF, чтобы корректно настроить правила разбора.

## Настройка интеграции с IdP в системе BAF​

### Настройка значений в чарте​

Для настройки интеграции необходимо заполнить секцию `idp` в файле `./values.baf.yaml`.

Описание полей секции:

- `enable` — включена ли интеграция с IdP. Необходимо установить значение `true`.
- `url` — URL созданного `realm` внутри IdP. На основе примера (Keycloak развернут по адресу `127.0.0.1:8080`) URL будет следующим: `http://127.0.0.1:8080/realms/baf/`. Если используется безопасный транспорт, укажите `https` вместо `http`.
- `claimParseRules` — правила разбора ключей и значений утверждений.
- `Idp__Debug` — режим отладки механизма аутентификации через IdP. Установка значения `true` включает специальный режим логирования, позволяющий отследить, какие утверждения приходят от IdP, и как они разбираются системой.
- `Idp__UserIdPrincipalName` — имя утверждения, используемое как источник идентификатора пользователя. Рекомендуется оставить значение по умолчанию и менять его только при наличии проблем.
- `Idp__UsernamePrincipalName` — имя утверждения, используемое как источник имени пользователя. Рекомендуется оставить значение по умолчанию и менять его только при наличии проблем.
- `Idp__ClientId` — идентификатор клиента, созданного в IdP, который будет использоваться BAF.
- `Idp__ClientSecret` — конфигурация Kubernetes-секрета, содержащего аутентификационный секрет клиента.
- `Idp__RequireHttps` — флаг, показывающий, требуется ли HTTPS-соединение для работы с IdP. Для тестов можно установить в `false`, для рабочей среды обязательно значение `true`.

Пример конфигурации на основе примера подготовки IdP:

    idp:
      enable: "true"
      url: "http://127.0.0.1:8080/realms/baf/"
      claimParseRules:
        - KeyRule: 'role-<roleName>'
          ValueRule: '<workspaceId>'
        - KeyRule: 'grole-<roleName>'
          ValueRule: '<enabled>'
      envOverride:
        Idp__Debug:
          value: "true"
        Idp__ClientId:
          value: "baf-client"
        Idp__RequireHttps:
          value: "false"

### Составление правил разбора​

Система BAF использует собственный синтаксис для разбора claims. Напомним, что claim состоит из двух частей: ключ и значение. Обе части могут содержать полезные данные, поэтому правило разбора состоит из двух частей: правило для ключа (`KeyRule`) и правило для значения (`ValueRule`).

Синтаксис следующий: все, что находится вне символов `<` и `>`, является структурными данными и должно полностью совпадать с текстом в правиле, чтобы правило применилось. Все, что заключено в угловые скобки, будет сохранено в одноименные переменные.

Переменные:

- `roleName` — имя роли.
- `workspaceId` — идентификатор рабочего пространства, в котором действует роль.
- `enabled` — флаг, указывающий, действительно ли данное утверждение с ролью активно. Значение должно быть логического типа (строка `true` или `false`). Этот флаг позволяет игнорировать claim, если IdP всегда отправляет его, даже когда значение пустое.

В системе может быть несколько правил. Это удобно, если форматы claims для глобальных и локальных ролей отличаются. Все claims, пришедшие от IdP, проверяются по порядку на соответствие каждому правилу из списка. Как только ключ и значение claim совпадают с каким-либо правилом, проверка для данного claim прекращается, и система переходит к следующему claim.

Логика обработки разобранных данных:

- Если заполнены переменные `roleName` и `workspaceId`, то пользователю добавляется локальная роль для указанного рабочего пространства.
- Если заполнена только переменная `roleName`, то пользователю добавляется глобальная роль.
- Если переменная `enabled` установлена в `false`, claim игнорируется, даже если разбор был успешным.

### Примеры​

Рассмотрим пример правила для локальной роли:

    KeyRule: 'role-<roleName>'
    ValueRule: '<workspaceId>'

Такое правило разберет claim `role-SuperAdmin: cb58a1f2-2985-4d9f-94b6-dc6ce03e2ca7` на переменные:

- `roleName` = `SuperAdmin`
- `workspaceId` = `cb58a1f2-2985-4d9f-94b6-dc6ce03e2ca7`

Сlaim `rrole-SuperAdmin: cb58a1f2-2985-4d9f-94b6-dc6ce03e2ca7` будет проигнорирован, так как ключ не совпадает с шаблоном.

примечание

Обратите внимание, что правило, состоящее полностью из переменных (например, `ValueRule: '<workspaceId>'`), будет принимать любые строки. Однако это может привести к ошибкам: например, claim `role-SuperAdmin: workspaceId-cb58a1f2...` при разборе значения `workspaceId` получит строку `workspaceId-cb58a1f2...`, которая не является корректным UUID, и это вызовет ошибку.

Теперь рассмотрим пример правила для глобальной роли:

    KeyRule: 'grole-<roleName>'
    ValueRule: '<enabled>'

Такое правило разберет claim `grole-SuperAdmin: false` на переменные:

- `roleName` = `SuperAdmin`
- `enabled` = `false`

Если переменная `enabled` отсутствует, она автоматически считается равной `true`.

### Режим отладки​

При включении режима отладки для интеграции с IdP любая попытка аутентификации через IdP будет генерировать дополнительные логи внутри поды `baf-dashboard-dep`.

В логах сначала выводится информация о пользователе из служебных claim, ключи которых задаются параметрами `Idp__UserIdPrincipalName` и `Idp__UsernamePrincipalName`:

    Start parsing claims
    User Id: 73254712-90c5-41ff-96e4-8c5e7e79185e
    User name: bafk

Далее выводится список полученных от IdP claims в формате `ключ: значение` и список правил (в формате `KeyRule ValueRule`, заданный в `claimParseRules`), которые проверялись для каждого claim.

Пример claims, которые не были распознаны ни одним правилом:

    - Claim: http://schemas.microsoft.com/claims/authnclassreference: 1
        Check rule: role-<roleName> <workspaceId>
        Check rule: grole-<roleName> <enabled>
    - Claim: email_verified: false
        Check rule: role-<roleName> <workspaceId>
        Check rule: grole-<roleName> <enabled>

Если какое-либо правило подходит, то выводятся переменные, извлеченные из ключа и значения.

примечание

Обратите внимание, что и ключ, и значение должны быть успешно разобраны, иначе claim пропускается.

Пример claim, распознанного как глобальная роль:

    - Claim: grole-superAdmin: true
        Check rule: role-<roleName> <workspaceId>
        Check rule: grole-<roleName> <enabled>
        Key parsed.
        Current data:
            Role: superAdmin
            Enabled: True
            Workspace id:
        Value parsed.
        Current data:
            Role: superAdmin
            Enabled: True
            Workspace id:
    Add global role: SuperAdmin.

Пример claim, распознанного как локальная роль:

    - Claim: role-Applicant Reader: 656309de-e5e8-471c-a2b3-7f9ac32ba5ee
        Check rule: role-<roleName> <workspaceId>
        Key parsed.
        Current data:
            Role: Applicant Reader
            Enabled: True
            Workspace id:
        Value parsed.
        Current data:
            Role: Applicant Reader
            Enabled: True
            Workspace id: 656309de-e5e8-471c-a2b3-7f9ac32ba5ee
    Add workspace role: Applicant Reader. Workspace ID: 656309de-e5e8-471c-a2b3-7f9ac32ba5ee.