DevOps

Как заполнить picture в Keycloak из VK и Yandex OAuth

Настройка Keycloak: автоматическое заполнение атрибута picture из OAuth-провайдеров VK (photo_200) и Yandex (photo_url). Пошаговая инструкция по мапперам Identity Provider, scopes и экспорту в токены. Примеры JSON и отладка.

Как автоматически заполнить атрибут ‘picture’ в профиле пользователя Keycloak при авторизации через OAuth-провайдеры VK или Yandex?

Установлен и настроен Keycloak с поддержкой русских сервисов (VK, Yandex). В приложениях VK и Yandex созданы identity providers, настроено получение данных пользователя, включая фото профиля. В настройках realm Keycloak добавлен пользовательский атрибут ‘picture’ для ссылки на аватарку.

Как настроить маппинг или протокол-мапперы, чтобы атрибут ‘picture’ автоматически заполнялся ссылкой на фото из VK/Yandex при первом логине? Есть ли примеры конфигурации для этого?

Чтобы автоматически заполнить атрибут ‘picture’ в Keycloak при авторизации через VK или Yandex, создайте в realm пользовательский атрибут ‘picture’, добавьте для соответствующего Identity Provider mapper типа «User Attribute Importer» и укажите claim, который возвращает IdP (VK: photo_200, Yandex: photo_url). Настройте scope у IdP (VK — profile, Yandex — photo_url), выберите режим синхронизации: Import (однократно при первом входе) или Force (обновлять при каждом логине), и при необходимости пробросьте атрибут в ID/Access token через Client Scopes.


Содержание


Быстрая настройка keycloak для импорта picture

  1. В админке Keycloak создайте пользовательский атрибут picture в Realm → User Profile → Attributes.
  2. В Identity Providers → <VK или Yandex> → Advanced добавьте необходимые scopes (VK: profile; Yandex: photo_url).
  3. В Identity Providers → → Mappers → Add Mapper создайте mapper типа User Attribute Importer:
  • Claim (имя поля в токене/userinfo): photo_200 (VK) или photo_url (Yandex)
  • User Attribute: picture
  • Sync Mode: Import (заполнить при первом логине) или Force (обновлять каждый раз)
  1. (Опционально) Пробросьте picture в ID/Access token через Client Scopes (Mapper: User Attribute → Token Claim Name = picture).
  2. Проверьте: зайдите Users → пользователь → Attributes — поле picture должно содержать URL.

Подробные примеры и объяснения есть в статье про attribute mapping при OIDC-брокеринге: https://skycloak.io/blog/attribute-mapping-in-keycloak-during-oidc-identity-brokering/


Создание атрибута и настройка scopes IdP

  1. Создание атрибута:
  • Админ-консоль → Realm Settings → User Profile → Attributes → Create Attribute.
  • Присвойте имя picture, тип — String. Можно добавить Display Name (например, «Аватар»).
  • Не делайте атрибут обязательным, если не все провайдеры гарантируют наличие фото.
  1. Scopes у Identity Provider:
  • Админ-консоль → Identity Providers → выберите VK или Yandex → вкладка Advanced → поле Scopes.
  • Добавьте profile для VK (VK отдаёт поля фото в пределах scope profile) и photo_url для Yandex (если в приложении Yandex требуется отдельный scope; см. настройки приложения у Yandex).
  • Без нужных scope IdP может не вернуть поле с фото в id_token или userinfo.

Полезно: настройку маппинга атрибутов в токены клиентам описывает https://skycloak.io/blog/using-custom-user-attributes-in-keycloak-oidc-tokens/


Настройка маппера Identity Provider для VK и Yandex

Шаги (UI):

  • Identity Providers → выберите IdP (alias, который вы создали) → Mappers → Add Mapper.
  • Поля маппера:
  • Name: vk-picture / yandex-picture
  • Mapper Type: User Attribute Importer (или похожее название в вашей версии Keycloak)
  • Claim: photo_200 (VK) / photo_url (Yandex)
  • User Attribute: picture
  • Claim JSON Type: String
  • Sync Mode: IMPORT (заполнить только при первом логине) или FORCE (перезаписывать при каждом логине)

Почему разные режимы синхронизации? Если вы хотите, чтобы пользователи могли потом менять аватар локально в Keycloak и не терять изменения — используйте IMPORT. Если хотите всегда брать актуальное фото от провайдера — FORCE.

Нюансы для VK:

  • VK возвращает несколько размеров: photo_50, photo_100, photo_200. Выберите нужный claim (обычно photo_200).

Нюансы для Yandex:

  • В примерах встречается claim photo_url (проверьте, какой именно claim возвращает ваш Yandex-приложение). Добавление scope photo_url/соответствующего профайла обязательно.

Если у вас несколько IdP и вы не хотите, чтобы атрибуты перезаписывали друг друга, можно:

  • применять префиксы в именах атрибутов (например, picture_vk, picture_yandex), либо
  • использовать префиксный импорт (см. обсуждение в issue проекта): https://github.com/keycloak/keycloak/issues/39929

Базовая логика показана в официальной заметке по импорту атрибутов Identity Provider: https://knowledge.broadcom.com/external/article/345120/identity-provider-keycloak-authenticatio.html


Экспорт атрибута picture в токены клиента (Client Scopes)

Чтобы клиент (ваше приложение) увидел URL аватарки в ID token или в userinfo:

Вариант A — через Client Scopes (рекомендован):

  1. Admin Console → Client Scopes → Create → имя, например picture-scope.
  2. Выберите созданный scope → Mappers → Add Mapper:
  • Name: picture-to-token
  • Mapper Type: User Attribute
  • User Attribute: picture
  • Token Claim Name: picture
  • JSON Type: String
  • Включите: Add to ID token = ON, Add to access token = ON, Add to UserInfo = ON
  1. Привяжите Client Scope к клиенту (Clients → ваш клиент → Client Scopes).

Вариант B — прямо в настройках клиента:

  • Clients → ваш клиент → Mappers → Add Mapper (те же поля).

Пример маппера для клиента через Admin REST (типовой для Keycloak):

json
{
 "name": "picture",
 "protocol": "openid-connect",
 "protocolMapper": "oidc-usermodel-attribute-mapper",
 "config": {
 "user.attribute": "picture",
 "claim.name": "picture",
 "jsonType.label": "String",
 "id.token.claim": "true",
 "access.token.claim": "true",
 "userinfo.token.claim": "true"
 }
}

(Этот JSON — стандартный шаблон для маппинга user attribute → claim в OIDC-токены.)

Подробнее о передаче пользовательских атрибутов в токены — в руководстве: https://pretius.com/blog/keycloak-tutorial и https://skycloak.io/blog/using-custom-user-attributes-in-keycloak-oidc-tokens/


Примеры конфигурации (UI + JSON)

Пример Identity Provider mapper (примерный, формат может отличаться по версии Keycloak):

json
{
 "name": "vk-picture",
 "identityProviderMapper": "oidc-user-attribute-idp-mapper",
 "config": {
 "claim": "photo_200",
 "user.attribute": "picture",
 "syncMode": "IMPORT"
 }
}

Пример клиента/Client Scope mapper (повтор):

json
{
 "name": "picture",
 "protocol": "openid-connect",
 "protocolMapper": "oidc-usermodel-attribute-mapper",
 "config": {
 "user.attribute": "picture",
 "claim.name": "picture",
 "jsonType.label": "String",
 "id.token.claim": "true",
 "access.token.claim": "true",
 "userinfo.token.claim": "true"
 }
}

Совет: импорт/экспорт можно настроить через GUI (без JSON). Но если автоматизируете развёртывание — используйте Admin REST или экспорт realm в JSON и правку конфигурации.


Отладка и частые ошибки

Что проверить, если picture не появляется?

  • Возвращает ли провайдер claim с фото? Перехватите id_token/userinfo в браузере (Network → token/userinfo) и декодируйте на https://jwt.io.
  • Правильно ли указано имя claim? VK — photo_200/photo_100 и т.д.; Yandex — photo_url (зависит от приложения).
  • Добавлены ли соответствующие scopes у Identity Provider? Без них claim может не прийти.
  • Sync Mode: если вы ожидаете обновление фото при каждом логине — поставьте Force; если хотите заполнение только при первом входе — Import.
  • Проброшен ли атрибут в токен клиента? Проверьте Client → Mappers или Client Scopes и опции id.token.claim/access.token.claim/userinfo.token.claim.
  • Несколько IdP затирают атрибут — используйте отдельные user attributes (picture_vk / picture_yandex) или префиксы. См. обсуждение: https://github.com/keycloak/keycloak/issues/39929
  • Claim имеет сложную структуру (объект/массив) — стандартный User Attribute Importer ожидает строку; для сложных случаев нужен кастомный маппер или скрипт-маршрутизатор.
  • Где смотреть результат? Admin Console → Users → откройте конкретного пользователя → вкладка Attributes. Там будет picture с URL.

Что ещё полезно:

  • Включите подробное логирование при необходимости.
  • Сравните поведение в разных версиях Keycloak — названия мапперов/поля конфигурации могут измениться.
  • Если не уверены, какой claim приходит, сначала посмотрите raw id_token/userinfo — это решит 80% загадок.

Источники

  1. Attribute Mapping in Keycloak During OIDC Identity Brokering — пошаговый пример маппинга picture для VK/Yandex.
  2. Keycloak tutorial: Learn how to use this technology’s advanced features - Pretius — примеры маппинга атрибутов и передачи в токены.
  3. Identity Provider Keycloak Authentication Details — детали про Attribute Importer и режим синхронизации.
  4. Using Custom User Attributes in Keycloak OIDC Tokens — как экспортировать user attributes в токены через Client Scopes.
  5. Prefixed User Attribute Importer for OIDC IdP (GitHub issue) — обсуждение префиксов и поведения при нескольких IdP.
  6. Attribute Mapping when using Keycloak as a SAML SP — общий контекст по маппингу (описательно).
  7. Using Custom User Providers with Keycloak | Baeldung — дополнительные идеи по кастомизации (при сложных требованиях).

Заключение

Коротко: настройка keycloak сводится к трём шагам — создать атрибут picture в Realm, импортировать значение из токена через Identity Provider mapper (claim photo_200 для VK, photo_url для Yandex) и пробросить атрибут в токены клиента через Client Scopes. Хотите обновления на каждом логине — выбирайте Sync Mode = Force; предпочитаете единовременную запись — Import. Удачной настройки — и не забывайте проверить реальные токены (id_token/userinfo), чтобы точно знать имя claim, которое возвращает провайдер.

Авторы
Проверено модерацией
Модерация
Как заполнить picture в Keycloak из VK и Yandex OAuth