Настройка IAM#
Примечание
Может использоваться ПО с открытым исходным кодом Keycloak или аналогичная IAM-система.
В IAM для каждого тенанта создается отдельный клиент (OAuth client). Для клиента создается типовая ролевая модель и выполняется настройка маппинга привилегий на access-токен.
В рамках тенанта предоставляется возможность назначать роли для пользователей этого тенанта.
При обращении к DS Lab проверяется, была ли создана для пользователя сессия. Если нет, то он перенаправляется в Keycloak, где открывается форма аутентификации.
После прохождения аутентификации и авторизации Keycloak передает в DS Lab access-токен, содержащий список привилегий пользователя в разрезе доступных ему тенантов. Возможность работы пользователя в тенанте определяется наличием у него какой-либо привилегии в этом тенанте.
Пример содержимого jwt access token:
{
"exp": 1702289908,
"iat": 1702289608,
"jti": "70c26f8a-7be1-4964-a06d-670f244f1b4d",
"iss": "http://localhost:8080/realms/MyRealm",
"aud": [
"ds-lab",
"dslb#tenant1",
"account"
],
"sub": "52279d99-d188-4133-8832-d79cc47b8a15",
"typ": "Bearer",
"azp": "ds-lab",
"session_state": "df80cd2a-50de-447b-88e0-c845ff66fb0d",
"acr": "1",
"allowed-origins": [
"http://ds-lab.apps.sbt.ru",
"http://localhost:3000"
],
"realm_access": {
"roles": [
"default-roles-ds-lab",
"offline_access",
"uma_authorization"
]
},
"resource_access": {
"dslb#tenant1": {
"roles": [
"data-edit",
"ModelDeveloper",
"model-list",
"data-query",
"data-endpoints",
"data-dictionary"
]
},
"account": {
"roles": [
"manage-account",
"manage-account-links",
"view-profile"
]
}
},
"scope": "openid dslab profile email",
"sid": "df80cd2a-50de-447b-88e0-c845ff66fb0d",
"email_verified": false,
"preferred_username": "testuser",
"given_name": "",
"family_name": ""
}
В блоке кода выше:
iss— сконфигурированное имя issuer — URL сервера IAM;aud— сконфигурированное имя приложения-клиента (например, ds-lab) должно быть в списке в claim aud;scope— должен присутствовать, или проверять claim typ: Bearer (проверка для того, чтобы подтвердить, что это именно access token);resource_access— перечислены тенанты каждый со своим набором привилегий (и/или ролей — для удобства пользователя).
Имя для клиента IAM, представляющего тенант, рекомендуется составлять из фиксированного префикса и названия тенанта. Выбранный способ именования клиента необходимо соблюдать для всех тенантов.
Примечание
В Keycloak присутствуют клиенты, не относящиеся к тенантам. DS Lab позволяет исключить из обработки таких клиентов либо по заданному списку имен, либо по отсутствию префикса.
Для указания префикса клиентов-тенантов используется настройка DS Lab
check.jwt.tenant.prefixToChoose. Для указания списка имен клиентов, исключаемых из тенантов, используется настройка DS Labcheck.jwt.tenant.excludeTenants.
Возможность выполнения тех или иных действий с проектами в DS Lab определяется наличием у пользователя соответствующих привилегий. Пользователь получает привилегии путем назначения ему ролей, агрегирующих привилегии.
Рекомендуется именовать роли с заглавной буквы, так их будет легче отличать от привилегий, имена которых начинаются со строчной буквы.
Пример настройки интеграции c внешней IAM-системой (Keycloak)#
В данном разделе описывается настройка DS Lab в режиме интеграции с внешней IAM-системой на примере ПО с открытым исходным кодом Keycloak.
Инструкция описана для Keycloak версии 22.0.3. Для других версий интерфейс может отличаться, но принцип взаимодействия остается тем же.
Установка и конфигурирование Keycloak для DS Lab#
Необходимо выполнить следующие действия:
Установить и настроить сервис Keycloak согласно эксплуатационной документации данного ПО.
Создать Realm для инсталляции DS Lab. Для этого:
Открыть UI установленного в п.1 сервиса Keycloak и войти с правами администратора.
В левом верхнем углу раскрыть список доступных Realm (по умолчанию «из коробки» доступен только «realm master») и нажать на кнопку Create Realm.

В открывшемся окне ввести наименование в поле Realm name (на рисунке это — «ds-lab») и нажать Create.

Все последующие действия будут производиться в Realm «ds-lab».
Создать Client (клиента) для приложения DS Lab.
Для создания клиента, под которым DS Lab будет обращаться к Keycloak, необходимо:
Перейти на вкладку Clients и нажать Create client.

Ввести имя клиента (на рисунке это — «ds-lab») и нажать Next.

На следующей странице нажать Next.

На следующей странице в полях Valid Redirect URIs и Web Origins прописать адрес сервиса DS Lab. Проверить, что пункт Standard flow* выбран.

Нажать Save. В списке клиентов должен появиться созданный клиент. Перейти на страницу клиента.

Настроить формирование claim aud для access-токена.
Создать дополнительный client scope. Перейти на страницу Client scopes и нажать кнопку Create client scope.

В открывшемся окне ввести имя нового client scope, на рисунке это — «dslab». Нажать Save.

В созданном client scope перейти во вкладку Mappers и выбрать Configure a new mapper.

Во всплывающем окне выбрать Audience.

В открывшемся окне задать имя mapper. Выбрать клиента DS Lab (на рисунке это — «ds-lab»). Выставить флаг Add to ID token. Нажать Save.

Перейти на страницу Clients, выбрать клиента «ds-lab». Перейти на вкладку Client scopes. Нажать Add client scope.

Во всплывающем окне выбрать созданный client scope ds-lab. Нажать Add -> Default.

Конфигурирование DS Lab для работы с Realm Keycloak#
Необходимо выполнить следующие действия:
Выгрузить значения JWKS для соответствующего Realm, сделав HTTP-запрос по адресу вида
{адрес keycloak}/auth/realms/MyRealm/protocol/openid-connect/certs.В DS Lab задать URL IAM, Realm и Client, указав в настройке
check.iam.infoсоответствующую JSON-структуру (например,{ "url": "", "realm": "{value}", "clientId": "{value}" }).Указать полученный в п.1 JWKS в настройке
check.jwt.jwks.
После выполнения перечисленных действий пользователи UI DS Lab перед началом работы будут переадресовываться для аутентификации на страницу Keycloak IAM, создавая необходимую для работы с DS Lab JWT-сессию.
Создание нового тенанта#
В этом примере создание тенанта включает в себя:
создание клиента (client) в Keycloak;
создание предопределенного набора привилегий DS Lab (в виде набора ролей первого уровня);
создание списка ролей пользователей (в виде композитных ролей).
В примере тенант создается путем импорта из файла, созданного по шаблону client-roles-template.json. В шаблоне вместо имени фактического тенанта указана метка-заполнитель «${tenantName}».
Пример создания тенанта с именем «dslb#tenant1»:
Подготовить файл импорта. Для этого:
Открыть файл-шаблона client-roles-template.json.
Заменить все вхождения строки «${tenantName}» на имя создаваемого тенанта «dslb#tenant1».
Сохранить файл с новым именем. Должен получиться файл со следующим содержимым:
{ "roles": { "client": { "dslb#tenant1": [ {"name": "model-config-view","composite": false,"clientRole": true,"attributes": {}}, {"name": "model-import", "composite": false,"clientRole": true,"attributes": {}}, {"name": "data-query", "composite": false,"clientRole": true,"attributes": {}}, {"name": "model-deploy", "composite": false,"clientRole": true,"attributes": {}}, {"name": "model-edit", "composite": false,"clientRole": true,"attributes": {}}, {"name": "data-endpoints", "composite": false,"clientRole": true,"attributes": {}}, {"name": "security-edit", "composite": false,"clientRole": true,"attributes": {}}, {"name": "data-dictionary", "composite": false,"clientRole": true,"attributes": {}}, {"name": "model-export", "composite": false,"clientRole": true,"attributes": {}}, {"name": "model-config-edit","composite": false,"clientRole": true,"attributes": {}}, {"name": "data-edit", "composite": false,"clientRole": true,"attributes": {}}, {"name": "model-create", "composite": false,"clientRole": true,"attributes": {}}, {"name": "model-delete", "composite": false,"clientRole": true,"attributes": {}}, {"name": "model-list", "composite": false,"clientRole": true,"attributes": {}}, {"name": "model-view", "composite": false,"clientRole": true,"attributes": {}}, {"name": "security-view", "composite": false,"clientRole": true,"attributes": {}}, { "name": "ModelAdmin", "description": "model-create, model-deploy, model-delete, model-config-view, model-config-edit, model-list", "composite": true,"composites": {"client": {"dslb#tenant1": ["model-list","model-create","model-config-view","model-config-edit","model-deploy","model-delete"]}}, "clientRole": true,"attributes": {} }, { "name": "ModelDeveloper", "description": "model-list, data-query, data-edit, data-endpoints, data-dictionary", "composite": true,"composites": {"client": {"dslb#tenant1": ["model-list","data-endpoints", "data-edit","data-query","data-dictionary"]}}, "clientRole": true,"attributes": {} }, { "name": "ModelSecurityViewer", "description": "security-view, model-list", "composite": true,"composites": {"client": {"dslb#tenant1": ["model-list","security-view"]}}, "clientRole": true,"attributes": {} }, { "name": "ModelSecurityEditor", "composite": true,"composites": {"client": {"dslb#tenant1": ["model-list","security-view","security-edit"]}}, "clientRole": true,"attributes": {} }, { "name": "TenantOperator", "description": "model-import, model-export, model-view, model-deploy, model-config-view, data-endpoints, model-list, data-dictionary", "composite": true,"composites": {"client": {"dslb#tenant1": ["model-list", "model-view", "model-config-view","model-import","data-endpoints", "model-deploy", "data-dictionary", "model-export"]}}, "clientRole": true,"attributes": {} }, { "name": "ModelViewer", "composite": true,"composites": {"client": {"dslb#tenant1": ["model-list","model-view"]}}, "clientRole": true,"attributes": {} }, { "name": "DataQuery", "description": "model-list, data-query", "composite": true,"composites": {"client": {"dslb#tenant1": ["model-list","data-query"]}}, "clientRole": true,"attributes": {} }, { "name": "ModelEditor", "composite": true,"composites": {"client": {"dslb#tenant1": ["model-list","model-view","model-edit","model-create","model-import"]}}, "clientRole": true,"attributes": {} }, { "name": "Tenant Admin", "composite": true,"composites": {"client": {"dslb#tenant1": []}}, "clientRole": true,"attributes": {} } ] } }, "clients": [ { "clientId": "dslb#tenant1", "enabled": true, "protocol": "openid-connect", "publicClient": true, "fullScopeAllowed": true, "standardFlowEnabled": true, "implicitFlowEnabled": false, "directAccessGrantsEnabled": false, "serviceAccountsEnabled": false } ] }Импортировать файл тенанта в realm. Для этого:
Перейти на страницу Realm settings, раскрыть меню Action и выбрать Partial import.

Во всплывающем окне выбрать подготовленный на шаге 1 файл импорта (на рисунке ниже — 1).
В окне отображения содержимого файла убедиться, что используется нужное имя клиента-тенанта (на рисунке ниже — 2).
Выбрать импорт клиента и ролей (на рисунке ниже — 3).
Выбрать действие, применяемое при существовании импортируемого объекта (рекомендуемое значение — «skip») (на рисунке ниже — 4). Нажать Import (на рисунке ниже — 5).

Должно появиться окно, аналогичное представленному ниже.

Перейти на страницу соответствующего клиента-тенанта во вкладку Roles и убедиться, что привилегии и базовые роли успешно импортировались.

При необходимости можно вручную добавить дополнительные роли, назначив им необходимые привилегии или скорректировать импортированные роли:
Для создания роли нажать Create.

В открывшемся окне указать наименование роли.

Привязать нужные привилегии к созданной роли. Для этого:
Нажать Action и выбрать Add associated roles.

Во всплывающем окне необходимо переключить фильтр на фильтрацию по ролям клиентов, а не realm (на рисунке ниже — 1).
Дополнительно можно задать фильтр по имени роли или тенанта (на рисунке ниже — 2).
Выбрать необходимые привилегии (на рисунке ниже — 3) и нажать Assign (на рисунке ниже — 4).


Примечание
Создание клиента и ролей можно выполнить вручную, но привилегии рекомендуется всегда импортировать из файла.
Ручное создание тенанта#
Создание клиента-тенанта аналогично созданию клиента «ds-lab» с тем отличием, что не указываются URL (т.к. обращений к Keycloak под этими клиентами не предусматривается).
Для примера создадим клиент-тенант «dslb#tenant1»:



На странице клиента-тенанта не должно быть вкладки Credentials.

Назначение пользователям ролей#
Для назначения пользователю ролей необходимо выполнить следующие действия:
При необходимости добавить в realm нового пользователя:
Перейти на страницу Users и добавить нового пользователя «testuser».


На вкладке Credentials задать пользователю пароль (временный или постоянный):


Назначить пользователю роли:
Перейти на страницу Users, открыть вкладку Role mappings и нажать Assign role.

В фильтре выбрать Filter by client, выделить нужные роли (в примере — роль «ModelDeveloper»).

Сняв флаг Hide inherited roles, можно увидеть полный перечень привилегий, назначенных пользователю.

Проверка настройки#
Для проверки настройки необходимо просмотреть состав формируемого пользователю access-токена. Для этого:
Перейти на страницу Clients (на рисунке ниже — 1), выбрать клиента «ds-lab».
Далее перейти на вкладку Client Scopes (на рисунке ниже — 2) и выбрать нужного пользователя из выпадающего списка (на рисунке ниже — 3).
Выбрать Generated access token (на рисунке ниже — 4). Перечень ролей и привилегий пользователя в разрезе доступных тенантов будет приведен в claim
resource_access.
Внимание!
Нужно убедиться, что в claim
audприсутствуетds-lab, если же нет — проверить, что действия по созданиюclient scopesдля клиента ds-lab выполнены в полном объеме.
Интеграция с IAM-Proxy#
IAM-Proxy выступает в роли граничного прокси, координирующего фронтальную аутентификацию и авторизацию. Может использоваться как единая точка входа. Предварительно необходимо убедиться, что должным образом сконфигурирован proxy-сервер. Для настройки proxy-сервера рекомендуется ознакомиться с документацией компонента IAM Proxy (AUTH) продукта Platform V IAM (IAM).
В DS Lab предусмотрены параметры, обеспечивающие работу в связке с proxy-сервером. Необходимо внести изменения в конфигурацию приложения в секцию overrideProperties:
dslb.integration.iamProxy.enable. Возможные значения:true— интеграция с IAM-Proxy включена. В данном случае работа по обогащению jwt-токена значениями для авторизации будет происходить с участием сконфигурированного внешнего proxy-сервера.false— интеграция отключена.
Важно отметить, что для корректной работы интеграции необходимо наличие значения параметра jwks в секции настроек системы разграничения прав
check.jwt.jwks. За счет этого выполняется условие проверки jwt-токена, полученного от прокси во время перенаправления.dslb.integration.iamProxy.urlPrefix— позволяет задать пользовательский префикс для url, участвующий в формировании ссылки на веб интерфейс DS Lab.Например,
urlPrefix: /test/toolsприведет к формированию ссылки вида:http://{ingress.host}/test/tools/service/dataspace. Данный параметр также работает и при выключенной интеграции с iam.