Stronghold может выступать OIDC-провайдером (OpenID Provider) для приложений, которые поддерживают вход через OpenID Connect. Пользователь входит в Stronghold любым настроенным методом аутентификации, а приложение получает ID-токен с данными сущности Stronghold: имя, адрес почты, группы.
Цель
Подключить внутреннее приложение (в примере — Grafana) к OIDC-провайдеру Stronghold так, чтобы входить могли только участники группы grafana-users, а приложение получало адрес почты и список групп пользователя.
Предварительные требования
Перед началом подготовьте:
- Токен Stronghold с правами на
identity/*. - Настроенный метод аутентификации для пользователей (например, OIDC через Dex в DP или
userpass). - Группа Identity
grafana-users, в которую входят сущности пользователей, и метаданныеemailу сущностей. - Внешний адрес Stronghold, доступный браузерам пользователей и приложению, — в примерах
https://stronghold.example.com.
Сущности, группы и псевдонимы описаны в разделе «Идентификационные данные (Identity)».
Шаг 1. Создайте ключ подписи
Создайте ключ apps, которым подписываются ID-токены:
d8 stronghold write identity/oidc/key/apps algorithm=RS256 rotation_period=24h verification_ttl=24hКлюч автоматически ротируется раз в сутки, прежняя открытая часть доступна для проверки подписи ещё verification_ttl.
Шаг 2. Ограничьте круг пользователей
Назначение (assignment) задаёт сущности и группы, которым разрешён вход через клиентское приложение:
GROUP_ID=$(d8 stronghold read -field=id identity/group/name/grafana-users)
d8 stronghold write identity/oidc/assignment/grafana-users group_ids="$GROUP_ID"Встроенное назначение allow_all разрешает вход всем сущностям — не используйте его для рабочих приложений.
Шаг 3. Создайте области действия
Области действия (scopes) добавляют в ID-токен утверждения (claims) по шаблону. Синтаксис шаблонов тот же, что у шаблонных политик.
d8 stronghold write identity/oidc/scope/email description="Адрес почты пользователя" template='{"email": {{identity.entity.metadata.email}}}'
d8 stronghold write identity/oidc/scope/groups description="Группы пользователя" template='{"groups": {{identity.entity.groups.names}}}'Параметр template принимает как строку JSON, так и значение в кодировке base64.
Шаг 4. Создайте клиентское приложение
Создайте клиент grafana с URI перенаправления приложения, назначением и ключом подписи:
d8 stronghold write identity/oidc/client/grafana redirect_uris="https://grafana.example.com/login/generic_oauth" assignments="grafana-users" key="apps" id_token_ttl=30m access_token_ttl=1hРазрешите клиенту использовать ключ apps:
CLIENT_ID=$(d8 stronghold read -field=client_id identity/oidc/client/grafana)
d8 stronghold write identity/oidc/key/apps allowed_client_ids="$CLIENT_ID"Шаг 5. Создайте провайдер
Создайте провайдер internal и разрешите клиенту использовать его:
d8 stronghold write identity/oidc/provider/internal issuer="https://stronghold.example.com" allowed_client_ids="$CLIENT_ID" scopes_supported="email,groups"Получите параметры для настройки приложения:
d8 stronghold read identity/oidc/client/grafana
curl -s https://stronghold.example.com/v1/identity/oidc/provider/internal/.well-known/openid-configuration | jqИз ответов понадобятся client_id, client_secret, issuer, authorization_endpoint, token_endpoint и userinfo_endpoint.
Шаг 6. Настройте приложение
Пример настройки Grafana (раздел auth.generic_oauth в grafana.ini):
[auth.generic_oauth]
enabled = true
name = Stronghold
client_id = <CLIENT_ID>
client_secret = <CLIENT_SECRET>
scopes = openid email groups
auth_url = https://stronghold.example.com/ui/stronghold/identity/oidc/provider/internal/authorize
token_url = https://stronghold.example.com/v1/identity/oidc/provider/internal/token
api_url = https://stronghold.example.com/v1/identity/oidc/provider/internal/userinfo
email_attribute_path = email
groups_attribute_path = groups<CLIENT_ID> и <CLIENT_SECRET> — значения client_id и client_secret из ответа identity/oidc/client/grafana.
Храните client_secret в Stronghold и доставляйте в приложение так же, как другие секреты, например через Stronghold Agent или интеграцию с Kubernetes.
Проверка
Проверьте результат:
Откройте приложение и выберите вход через Stronghold. Браузер перенаправит вас на страницу входа Stronghold, после входа — обратно в приложение.
Войдите пользователем, не входящим в группу
grafana-users, — вход должен быть отклонён.Проверьте содержимое ID-токена в журнале приложения или декодируйте его: должны присутствовать
iss,aud(равныйclient_id),emailиgroups.Проверьте, что открытые ключи доступны:
curl -s https://stronghold.example.com/v1/identity/oidc/provider/internal/.well-known/keys | jq '.keys[].kid'
Очистка
Удалите объекты, созданные в этом руководстве:
d8 stronghold delete identity/oidc/provider/internal
d8 stronghold delete identity/oidc/client/grafana
d8 stronghold delete identity/oidc/scope/email
d8 stronghold delete identity/oidc/scope/groups
d8 stronghold delete identity/oidc/assignment/grafana-users
d8 stronghold delete identity/oidc/key/apps