Аутентификация пользователей с OpenID и Keycloak
Важно
Инструкция действительна только для серверной версии ТестОпс 5.6.4 и выше.
ТестОпс реализует стандартный Spring Boot OpenID клиент.
Предварительные условия
Для успешной настройки и использования OpenID с Keycloak необходимо выполнить следующие требования.
- Вам нужен административный доступ к Keycloak или администратор Keycloak рядом с вами во время процесса настройки.
- Вам нужен доступ к конфигурационным файлам ТестОпс.
- Вам нужно иметь возможность применять изменения в конфигурации, что может потребовать некоторого времени простоя.
- Оба Keycloak и ТестОпс должны использовать один и тот же протокол для связи, т.е. если одна из систем работает за HTTPS, то обе системы должны работать за HTTPS, т.е. должен быть что-то вроде обратного прокси, который позволит использовать HTTP между серверами ТестОпс и Keycloak. Пожалуйста, проконсультируйтесь с вашим сетевым администратором или DevOps для обеспечения правильной настройки на стороне сети.
Интеграция ТестОпс и Keycloak
Дальнейшие примеры будут использовать фиктивные адреса, которые в вашем случае будут отличаться.
Предположим следующее.
- ТестОпс развернут и доступен по адресу http://testops.local.
- Keycloak развернут и доступен по адресу http://keycloak.local.
Последовательность
Что нужно сделать, если нам нужно синхронизировать группы Keycloak с глобальными ролями ТестОпс.
- Создать новое пространство (Realm) на стороне Keycloak (опционально).
- Создать OpenID клиент на стороне Keycloak в пространстве, которое вы собираетесь использовать (обязательно).
- Определить роли и группы Realm.
- Определить scope клиента.
- Добавить пользователей и назначить роли и группы.
- Выполнить настройку на стороне ТестОпс.
Настройка на стороне Keycloak
Опционально, создать новое пространство (Realm) в Keycloak
Создайте новое пространство (Realm), если вы хотите, чтобы пользователи ТестОпс находились в отдельном пространстве.
Создать новый OpenID клиент для ТестОпс
ТестОпс будет OpenID клиентом для Keycloak.
Переключитесь на пространство (Realm), которое предназначено для работы с ТестОпс.
Перейдите в раздел Клиенты в интерфейсе Keycloak и нажмите Создать клиента.
При создании нового клиента установите Действительные URI перенаправления: http://testops.local/login/oauth2/code/keycloak.
Завершите настройку, сохранив данные нового клиента.
Определить роли и группы Realm
Примечание
Этот шаг необходим, если вы хотите синхронизировать группы Keycloak с глобальными ролями ТестОпс, т.е. члены определенной группы в Keycloak получат глобальные роли ТестОпс ROLE_ADMIN
или ROLE_USER
.
ТестОпс синхронизирует глобальные роли с группами на стороне Keycloak.
На стороне Keycloak создайте две роли: одну для группы пользователей, которые будут администраторами на стороне ТестОпс, и другую для группы. В нашем примере мы будем использовать роль и ato_admins
для пользователей ТестОпс, которые должны быть администраторами (ROLE_ADMIN
), и ato_users
для тех, кто будет получать роль ROLE_USER
.
- Перейдите в Realm roles в пространстве, где ТестОпс зарегистрирован как OpenID клиент.
- Создайте 2 роли:
ato_admins
,ato_users
.
- Перейдите в Группы.
- Создайте 2 группы:
ato_admins
,ato_users
.
- Перейдите к настройке
ato_admins
Сопоставление ролей.- Добавьте роль
ato_admins
в список ролей.
- Добавьте роль
- Перейдите к настройке
ato_users
Сопоставление ролей.- Добавьте роль
ato_users
в список ролей.
- Добавьте роль
Теперь у нас есть 2 группы, которым назначены роли.
Определить scope клиента
Чтобы информация о назначенных группах для определенного пользователя была доступна для ТестОпс, нам нужно добавить новую область в качестве OpenId клиента на стороне Keycloak.
- Перейдите в Client scopes.
- Нажмите Create client scope.
- Назовите область (мы назовем область
groups
для примера).- Назначьте тип По умолчанию создаваемой области.
- Установите флажок Включить в scope токена, так как нам нужна эта информация в токене доступа для ТестОпс (см. ниже).
- Перейдите к настройкам созданной области.
- Переключитесь на вкладку Mappers
- Нажмите Add mapper и в выпадающем списке выберите from predefined mappers.
- Выберите маппер под названием groups и сделайте эту область по умолчанию.
Проверка содержимого токена доступа
Вы можете попробовать получить токен доступа от Keycloak. Это упражнение может быть полезным при устранении неполадок, если что-то пойдет не так с синхронизацией ролей. Поэтому сейчас вы можете легко пропустить этот шаг.
ТестОпс получит access token от Keycloak после успешной попытки аутентификации. Токен доступа будет содержать информацию о пользователе, который входит в ТестОпс, используя Keycloak в качестве поставщика идентификации (или IAM).
Выполните API вызов с помощью curl или любого другого инструмента, к которому вы привыкли.
shell
USERNAME=name of any user registered in Keycloak for TestOps OpenId
U_PASSWORD=password for the user above
CLIENT_ID=testops
RESPONSE=$(curl -X POST 'http://keycloak.local/realms/testops-realm/protocol/openid-connect/token' \
--data-urlencode "client_id=${CLIENT_ID}" \
--data-urlencode 'grant_type=password' \
--data-urlencode 'scope=openid' \
--data-urlencode "username=${USERNAME}" \
--data-urlencode "password=${U_PASSWORD}")
ACCESS_TOKEN=$(echo $RESPONSE | jq .access_token)
echo "$ACCESS_TOKEN"
Затем вам нужно декодировать полученный токен доступа, например, используя JWT debug tool.
Затем выполните форматирование содержимого JSON (мы удалили содержимое, которое не представляет интереса для ясности).
JSON
{
"exp": 1703517143,
"iat": 1703516843,
"jti": "62b7bd96-a982-4063-9c97-f12dbe1553f8",
"iss": "http://keycloak.local/realms/testops-realm",
"typ": "Bearer",
"azp": "testops",
"acr": "1",
"scope": "openid profile email groups",
"sid": "043242d3-3c67-4ad7-8795-46c0df9f745e",
"email_verified": true,
"name": "Bugs Bunny",
"groups": [
"default-roles-testops",
"ato_admins",
"offline_access",
"uma_authorization"
],
"preferred_username": "bugsbunny",
"given_name": "Bugs",
"family_name": "Bunny",
"email": "[email protected]"
}
Таким образом, область groups содержит информацию о группе ato_admins
, она будет использоваться для функции синхронизации ролей.
Добавить пользователей и назначить роли и группы
Теперь вам нужно добавить пользователей Keycloak и распределить их между соответствующими группами, чтобы синхронизировать их группы в Keycloak с глобальными ролями ТестОпс. Вы можете пропустить этот шаг, если собираетесь управлять глобальными ролями в ТестОпс.
Выполните настройку на стороне ТестОпс
Получите эндпоинты провайдера OpenID
Для правильной интеграции между провайдером OpenID и ТестОпс как клиентом OpenID, на стороне ТестОпс необходимо настроить только три эндпоинта:
- tokenUri,
- jwksSetUri,
- authorizationUri.
Чтобы получить эти URI-параметры, перейдите в Keycloak в раздел Realm settings. На вкладке General найдите раздел Endpoints и нажмите на ссылку OpenID Endpoint Configuration. Эта ссылка направит вас на страницу http://keycloak.local/realms/testops-realm/.well-known/openid-configuration, которая является JSON-файлом, содержащим все эндпоинты для текущего Realm.
JSON
{
"issuer": "http://keycloak.local/realms/testops-realm",
"authorization_endpoint": "http://keycloak.local/realms/testops-realm/protocol/openid-connect/auth",
"token_endpoint": "http://keycloak.local/realms/testops-realm/protocol/openid-connect/token",
"introspection_endpoint": "http://keycloak.local/realms/testops-realm/protocol/openid-connect/token/introspect",
"userinfo_endpoint": "http://keycloak.local/realms/testops-realm/protocol/openid-connect/userinfo",
"end_session_endpoint": "http://keycloak.local/realms/testops-realm/protocol/openid-connect/logout",
"frontchannel_logout_session_supported": true,
"frontchannel_logout_supported": true,
"jwks_uri": "http://keycloak.local/realms/testops-realm/protocol/openid-connect/certs",
"check_session_iframe": "http://keycloak.local/realms/testops-realm/protocol/openid-connect/login-status-iframe.html",
"grant_types_supported": [
"authorization_code",
"implicit",
"refresh_token",
"password",
"client_credentials",
"urn:openid:params:grant-type:ciba",
"urn:ietf:params:oauth:grant-type:device_code"
],
"acr_values_supported": [
<...>
}
С открытой страницы вам понадобятся следующие эндпоинты:
- token_endpoint,
- jwks_uri,
- authorization_endpoint.
Настройка ТестОпс для использования Keycloak с OpenId
В зависимости от выбранного типа развертывания настройка должна быть выполнена в разных файлах, и имена параметров будут выглядеть немного по-разному с точки зрения конечного пользователя.
Ниже мы описываем параметры для официально поддерживаемых развертываний и параметры конфигурации, описанные в разделе развертывания.
Настройка клиента
Для развертывания Kubernetes вам нужно настроить интеграцию с Keycloak через переменные в разделе auth.openid
файла values.yaml.
На предыдущих этапах мы собрали информацию об эндпоинтах IdP OpenID. Эти эндпоинты соответствуют параметрам ТестОпс следующим образом:
- token_endpoint →
auth.openid.tokenUri
, - jwks_uri →
auth.openid.jwksSetUri
, - authorization_endpoint →
auth.openid.authorizationUri
.
yaml
# Это пример, который не будет работать без изменений.
auth:
primary: openid
defaultRole: ROLE_GUEST
<...>
openid:
enabled: true
clientName: testops
clientId: <your_client_ID_here>
providerName: keycloak
clientSecret: <your_client_secret_here>
redirectUri: https://testops.local/login/oauth2/code/keycloak
scope: openid, email, profile
authorizationGrantType: authorization_code
authorizationUri: http://keycloak.local/realms/testops-realm/protocol/openid-connect/auth
jwksSetUri: http://keycloak.local/realms/testops-realm/protocol/openid-connect/certs
tokenUri: http://keycloak.local/realms/testops-realm/protocol/openid-connect/token
usernameAttribute: preferred_username
defaultRole: ROLE_GUEST
syncRoles: false
groupRoleAttribute: groups
roleUserGroups: ato_users
roleAdminGroups: ato_admins
# параметры ниже в обычном режиме работы остаются пустыми
userinfoUri:
issuerUri:
firstNameAttribute:
lastNameAttribute:
Если OpenId через Keycloak предполагается использовать в качестве основного способа аутентификации пользователей в ТестОпс, то параметр auth.primary
должен быть установлен на openid
.
yaml
auth:
primary: openid
С этого момента доступ встроенного администратора должен осуществляться через URI http://testops.local/login/system.
Мы настоятельно рекомендуем установить глобальную роль по умолчанию для пользователей, которые входят в ТестОпс в первый раз, на ROLE_GUEST
. Поэтому параметр defaultRole
должен быть настроен следующим образом:
yaml
auth:
<...>
defaultRole: ROLE_GUEST
Этот подход обеспечит лучший контроль за использованием лицензий, так как ROLE_GUEST
не предоставляет прав на запись в систему и не занимает место в вашей лицензии.
Атрибуты синхронизации ролей будут объяснены в следующем разделе.
Настройка синхронизации ролей
Мотивация
Зачем нам нужна синхронизация ролей с Keycloak?
Синхронизация ролей обеспечивает лучший контроль над потреблением лицензий и предотвращает несанкционированный доступ конечных пользователей к проектам ТестОпс, а также позволяет управлять доступом к ТестОпс с помощью функций вашего IdP (IAM).
Как это работает
Необходимо создать группу на стороне IdP. Затем на стороне ТестОпс нужно настроить маппинг пользователей с этими группами. В зависимости от нахождения пользователей в этих группах ТестОпс назначит пользователю глобальную роль.
Примечание
В настоящий момент нет возможности синхронизировать группы на стороне IdP (IAM) c группами доступа к проектам.
Настройка синхронизации ролей
- На стороне Keycloak вам нужно иметь Настроенные роли и группы.
- Группы должны присутствовать в областях клиента.
Для развертывания в Kubernetes необходимо настроить все параметры в разделе auth.openid.syncRoles
файла values.yaml.
Ниже приведены настройки для раздела OpenID в values.yaml:
yaml
auth:
primary: openid
defaultRole: ROLE_GUEST
openid:
enabled: true
<...>
defaultRole: ROLE_GUEST
syncRoles: true
groupRoleAttribute: groups
roleUserGroups: ato_users
roleAdminGroups: ato_admins
<...>
Для того чтобы ТестОпс синхронизировал глобальные роли с группами Keycloak, необходимо установить следующие параметры:
defaultRole: ROLE_GUEST
— роль, которая присваивается пользователю при его первом входе в ТестОпс при помощи аутентификации через Keycloak;syncRoles: true
— включает синхронизацию;groupRoleAttribute: groups
— название параметра (claim), который содержит список групп, к которым относится пользователь;roleUserGroups: ato_users
— название группы на стороне Keycloak, участникам которой на стороне ТестОпс будет присвоена роль ROLE_ADMIN;roleAdminGroups: ato_admins
— название группы на стороне Keycloak, участникам которой на стороне ТестОпс будет присвоена роль ROLE_USER.
Примечание
Синхронизация ролей будет работать правильно только в случае, если auth.openid.defaultRole
установлено в ROLE_GUEST
.