Настройка SSO
В веб-интерфейсе YTsaurus реализовано два типа аутентификации пользователей: по паролю и через SSO. Как работать с паролями — написано в Руководстве пользователя. В данной статье описано, как сконфигурировать SSO.
Важно
YTsaurus поддерживает SSO-аутентификацию только по протоколу OAuth 2.0. При настройке SSO выбирайте такой Identity Server, который поддерживает работу с OAuth.
Конфигурация
Для корректной работы аутентификации необходимо настроить две компоненты: прокси и веб-интерфейс.
-
Чтобы настроить прокси, следует заполнить поле
oauthServiceв спецификации ресурса ytsaurus. -
Для конфигурации веб-интерфейса необходимо задать настройку ytOAuthSettings в конфиге веб-интерфейса. Сделать это можно через ui-helm-chart, заполнив поле
settings.oauthвvalues.yaml.
Пример
Microsoft Identity Platform
Ниже приведён пример — как настроить SSO-аутентификацию в YTsaurus с помощью сервиса Microsoft Identity Platform.
-
Сначала необходимо завести OAuth-приложение в MS Identity Platform. В качестве RedirectURIs следует задать
https://<HOST_NAME_OF_YOUR_YT_CLUSTER>/api/oauth/callback.При создании приложения будут получены
CLIENT_IDиCLIENT_SECRET. Также потребуется определитьTENANT_ID— узнать его можно у администратора OAuth-сервера. Полученные параметры необходимо будет указывать в спецификации веб-интерфейса. -
Далее следует настроить сервер:
# ytsaurus.yaml apiVersion: cluster.ytsaurus.tech/v1 kind: Ytsaurus metadata: name: ytdemo spec: oauthService: host: graph.microsoft.com port: 443 secure: true userInfoHandler: endpoint: oidc/userinfo loginField: email # ... -
Настройка веб-интерфейса будет выглядеть следующим образом:
# ui-helm.values.yaml ui: image: repository: ghcr.io/ytsaurus/ui # ... settings: oauth: enabled: false baseURL: "https://login.microsoftonline.com/mycompany.onmicrosoft.com/oauth2/v2.0/" # mycompany.onmicrosoft.com is a tenant ID example authPath: "authorize" logoutPath: "logout" tokenPath: "token" clientIdEnvName: "CLIENT_ID" clientSecretEnvName: "CLIENT_SECRET" scope: "openid offline_access" # offline_access scope is required for api to respond with refresh_token buttonLabel: "Login via SSO"
Keycloak
Ниже приведён пример настройки SSO-аутентификации с помощью Keycloak.
В примере используются realm ytsaurus.tech, адрес Keycloak https://keycloak.example.com и адрес веб-интерфейса https://ui.example.com. Keycloak должен быть доступен как из браузера пользователя, так и из HTTP-прокси.
-
Создайте в Keycloak клиент OpenID Connect. Включите Client authentication и Standard flow и задайте следующие параметры:
Valid redirect URIs: https://ui.example.com/api/oauth/callback Valid post logout redirect URIs: https://ui.example.com/api/oauth/logout/callback Web origins: https://ui.example.comСохраните полученные
CLIENT_IDиCLIENT_SECRETв Kubernetes Secret:kubectl create secret generic ytsaurus-ui-keycloak \ --from-literal=client-id='<CLIENT_ID>' \ --from-literal=client-secret='<CLIENT_SECRET>' -
Настройте сервер:
# ytsaurus.yaml apiVersion: cluster.ytsaurus.tech/v1 kind: Ytsaurus metadata: name: ytdemo spec: oauthService: host: keycloak.example.com port: 443 secure: true userInfoHandler: endpoint: "realms/ytsaurus.tech/protocol/openid-connect/userinfo" loginField: "preferred_username" errorField: "error" disableUserCreation: false # ...При
disableUserCreation: falseпользователь будет автоматически создан в//sys/usersпосле первого успешного входа. Права пользователю необходимо выдать отдельно. -
Настройте веб-интерфейс:
# ui-helm.values.yaml ui: clusterConfig: clusters: - id: my-cluster # Остальные параметры кластера опущены. authentication: basic env: - name: KEYCLOAK_CLIENT_ID valueFrom: secretKeyRef: name: ytsaurus-ui-keycloak key: client-id - name: KEYCLOAK_CLIENT_SECRET valueFrom: secretKeyRef: name: ytsaurus-ui-keycloak key: client-secret settings: oauth: enabled: true baseURL: "https://keycloak.example.com" authPath: "realms/ytsaurus.tech/protocol/openid-connect/auth" logoutPath: "realms/ytsaurus.tech/protocol/openid-connect/logout" tokenPath: "realms/ytsaurus.tech/protocol/openid-connect/token" clientIdEnvName: "KEYCLOAK_CLIENT_ID" clientSecretEnvName: "KEYCLOAK_CLIENT_SECRET" scope: "openid profile" buttonLabel: "Login via Keycloak"Значение
authentication: basicразрешает веб-интерфейсу передавать данные аутентификации HTTP-прокси и не требует включения входа по паролю. Secret с OAuth client secret не заменяет interface secret: в interface secret хранится токен YTsaurus для служебных запросов веб-интерфейса. -
Примените спецификацию кластера и установите или обновите веб-интерфейс с подготовленным
values.yaml. После входа Keycloak вернёт пользователя на/api/oauth/callback, а HTTP-прокси запроситuserinfoи возьмёт имя пользователя изpreferred_username.
Детали реализации
Ниже описано, как устроен флоу работы с OAuth. Это понимание поможет при локализации возможных проблем конфигурации.
- Пользователь открывает веб-интерфейс YTsaurus и нажимает "Login via SSO".
- Веб-интерфейс YTsaurus перенаправляет пользователя на URL стороннего OAuth Identity Server с пробросом сконфигурированных
scope. URL стороннего сервера формируется на основеbaseURLиauthPath. - Пользователь соглашается с запрошенными разрешениями, и OAuth Identity Server перенаправляет пользователя на адрес, который был задан в настройках OAuth-приложения —
https://<HOST_NAME_OF_YOUR_YT_CLUSTER>/api/oauth/callback. В query-параметреcodeпередаётся код авторизации. - Веб-интерфейс делает запрос в OAuth Identity Server по URL из
baseURLиtokenPath. В запросе передаются код авторизации и секрет приложения. В ответе приходятaccess_tokenиrefresh_token. - Веб-интерфейс выставляет токены в cookie браузера пользователя:
yt_oauth_access_tokenиyt_oauth_refresh_token. - Когда
yt_oauth_access_tokenистекает — веб-интерфейс обновляет его, используяyt_oauth_refresh_token. - Веб-интерфейс отправляет запросы в прокси, передавая значение cookie
yt_oauth_access_token. Прокси делает запрос в OAuth Identity Server на URL, который формируется на основеoauthService.host,oauthService.portиoauthService.userInfoHandler.endpoint. - Из полученного ответа достаётся поле, сконфигурированное в
oauthService.userInfoHandler.loginField— оно используется в качестве username пользователя YTsaurus.