Аутентификация пользователей с OpenID и Keycloak 
Важно
Инструкция действительна только для серверной версии ТестОпс.
ТестОпс реализует стандартный Spring Boot OpenID клиент.
Предварительные условия 
Для успешной настройки и использования OpenID с Keycloak необходимо выполнить следующие требования.
- Вам нужен административный доступ к Keycloak или администратор Keycloak рядом с вами во время процесса настройки.
- Вам нужен доступ к конфигурационным файлам ТестОпс.
- Вам нужно иметь возможность применять изменения в конфигурации, что может потребовать некоторого времени простоя.
- Инстансы Keycloak и ТестОпс должны использовать один и тот же протокол для связи, например, HTTPS. Пожалуйста, проконсультируйтесь с вашим сетевым администратором или DevOps для обеспечения правильной настройки на стороне сети.
Интеграция ТестОпс и Keycloak 
Дальнейшие примеры будут использовать фиктивные адреса, которые в вашем случае будут отличаться.
Предположим следующее.
- ТестОпс развернут и доступен по адресу https://testops.example.com.
- Keycloak развернут и доступен по адресу https://keycloak.local.
Последовательность 
Что нужно сделать, если нам нужно синхронизировать группы Keycloak с глобальными ролями ТестОпс.
- Создать новое пространство (Realm) на стороне Keycloak (опционально).
- Создать OpenID клиент на стороне Keycloak в пространстве, которое вы собираетесь использовать (обязательно).
- Определить роли и группы Realm.
- Определить scope клиента.
- Добавить пользователей и назначить роли и группы.
- Выполнить настройку на стороне ТестОпс.
Настройка на стороне Keycloak 
Опционально, создать новое пространство (Realm) в Keycloak 
Создайте новое пространство (Realm), если вы хотите, чтобы пользователи ТестОпс находились в отдельном пространстве.
Создать новый OpenID клиент для ТестОпс 
ТестОпс будет OpenID клиентом для Keycloak.
- Переключитесь на пространство (Realm), которое предназначено для работы с ТестОпс. 
- Перейдите в раздел Клиенты в интерфейсе Keycloak и нажмите Создать клиента.  
- При создании нового клиента установите Действительные URI перенаправления: https://testops.example.com/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 'https://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": "https://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. Эта ссылка направит вас на страницу https://keycloak.local/realms/testops-realm/.well-known/openid-configuration, которая является JSON-файлом, содержащим все эндпоинты для текущего Realm.
JSON
{
  "issuer": "https://keycloak.local/realms/testops-realm",
  "authorization_endpoint": "https://keycloak.local/realms/testops-realm/protocol/openid-connect/auth",
  "token_endpoint": "https://keycloak.local/realms/testops-realm/protocol/openid-connect/token",
  "introspection_endpoint": "https://keycloak.local/realms/testops-realm/protocol/openid-connect/token/introspect",
  "userinfo_endpoint": "https://keycloak.local/realms/testops-realm/protocol/openid-connect/userinfo",
  "end_session_endpoint": "https://keycloak.local/realms/testops-realm/protocol/openid-connect/logout",
  "frontchannel_logout_session_supported": true,
  "frontchannel_logout_supported": true,
  "jwks_uri": "https://keycloak.local/realms/testops-realm/protocol/openid-connect/certs",
  "check_session_iframe": "https://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: <ID клиента>
      providerName: keycloak
      clientSecret: <секретный ключ клиента>
      redirectUri: https://testops.example.com/login/oauth2/code/keycloak
      scope: openid, email, profile
      authorizationGrantType: authorization_code
      authorizationUri: https://keycloak.local/realms/testops-realm/protocol/openid-connect/auth
      jwksSetUri: https://keycloak.local/realms/testops-realm/protocol/openid-connect/certs
      tokenUri: https://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 https://testops.example.com/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.

