Clients
Клиенты - сущности, которые могут отправлять запрос в Keycloak на аутентификацию пользователя. Чтобы приложение могло использовать ресурсы keycloak, оно должно быть зарегистрировано. Клиенты делятся по идентификаторам.
Настройка через консоль управления реалмом, раздел клиенты. Желательно настраивать на каждый сервер / сервис отдельный клиент.
Раздел Clients
Client list
Client list - список клиентов. Параметры настройки клиента:
| Параметр | Описание |
| Client type | Алгоритм аутентификации клиента. OpenID или SAML. |
| Client ID | Идентификатор клиента. Он будет использоваться в запросах, поэтому желательно с маленькой буквы, без пробелов и прочего. |
| Client authentication |
Сможет ли приложение хранить секрет и использовать его для аутентификации на Keycloak. ON — Конфиденциальный клиент Приложение обязано хранить секрет. При обмене авторизационного кода на токены клиент предъявляет код и Client Secret. Используется для бэкенда. Пример: FastAPI приложение на сервере, обращающееся к Keycloak из защищенной среды. OFF — Публичный клиент У клиента нет секрета, при обмене кода на токены секрет не используется. Используется для одностраничных приложений, мобильных приложений. |
| Authorization |
Активация RBAC, доступ к конкретным строчкам в БД. OFF (выключено — поведение по умолчанию) Пользователю даются роли (например, user, admin), и клиент сам решает на своей стороне, что с этими ролями делать. Решение принимает бэкенд клиента. ON (включено — тонкая (fine-grained) авторизация) Как работает: Вы описываете ресурсы (например: Аккаунт №123, Документ "Отчет.xlsx"), области действий (read, write, delete) и политики (кто, при каких условиях может что делать). Keycloak сам принимает решение: разрешено или запрещено. Кто принимает решение: Keycloak (сервер авторизации). Ваше приложение: Спрашивает у Keycloak: «Может ли пользователь Вася выполнить read над ресурсом Аккаунт №123?» Keycloak отвечает: Permit или Deny.
После включения, в меню клиента появляются новые вкладки: Resources — что вы защищаете (например, Документы, Счета, Данные профиля). Authorization Scopes — действия (например, view, edit, delete, download). Policies — кто и при каких условиях может что-то делать (например, Только владелец ресурса, Только пользователи из отдела продаж, Только между 9:00 и 18:00). Permissions — связывание всего вместе: «Разрешить edit для ресурса Документ, если выполнена политика Владелец документа».
Включение Authorization усложняет архитектуру. Keycloak становится точкой принятия решений (PEP — Policy Enforcement Point на клиенте, PDP — Policy Decision Point на Keycloak). Это требует:
|
| Root URL | Базовый адрес вашего приложения. Используется как префикс для других URL, если они указаны относительно. Может быть пустым, но лучше указать. Некоторые функции Keycloak (например, ссылка "Back to application" на странице логина) используют этот URL. |
| Home URL | Куда пользователь попадет после нажатия на логотип Keycloak или ссылку "Back to application".
Отличие от Root URL: Root URL — это база/префикс. Home URL — конкретная страница, которая считается "домашней" для приложения. Если не указан, используется Root URL. |
| Valid Redirect URIs |
Адреса, на которые Keycloak разрешит отправлять авторизационный код или токены после успешной аутентификации.
Для безопасности критично. Как минимум указывать относительный. Просто * убивает всю авторизацию.
|
| Valid Post Logout Redirect URIs | Адреса, на которые Keycloak перенаправит пользователя после успешного выхода (logout).
Отличие от Valid Redirect URIs: Обычные редиректы — после входа (авторизации) Post Logout — после выхода Зачем нужно: Совет: Обычно указывают страницу вроде /goodbye, /logged-out или сам Root URL. |
| Web Origins |
Какие домены имеют право выполнять CORS-запросы к вашему Keycloak из браузера (для SPA-приложений). Используется для: CORS (Cross-Origin Resource Sharing) на эндпоинтах Keycloak (/token, /logout, /userinfo и т.д.). Пример для SPA на React: Если Web Origins указан правильно, браузер позволит SPA из myapp.com делать fetch-запросы к Keycloak. + Плюс означает использовать Valid Redirect URIs как список разрешенных источников * Любой источник (все домены) |
Клиенты по умолчанию в Master realm:
| Название | Описание | Адрес |
| account | Клиент пользовательского личного кабинета. Управление профилем, просмотр сеансов входа и разрешения. | /realms/{realm}/account |
| account-console | Фронтенд клиента account, вызывающий API account. |
|
| admin-cli | Клиент взаимодействия с Keycloak через CLI или REST API. Например получение токена через kcadm.sh или curl для скриптов/CI/CD. Поддерживает client_credentials и password гранты. |
|
| broker |
Внутренний клиент для федерации идентичности (SSO между провайдерами). Пример: Keycloak как Identity Broker между Google, GitHub и другим Keycloak сервером. |
|
| master-realm | Формальный клиент, представляющий сам master realm. Часто используется для определённых внутренних механизмов и ссылок в Admin Console. |
|
| security-admin-console | Клиент для административной консоли Keycloak. Используется при входе в админ-панель, управлении реалмами, пользователями и клиентами. | /admin/{realm}/console |
Пример работы с admin-cli:
import requests
def get_keycloak_token():
url = "http://192.168.1.195:9090/realms/master/protocol/openid-connect/token"
payload = {
"grant_type": "password",
"client_id": "admin-cli",
"username": "admin",
"password": "admin",
}
headers = {
"Content-Type": "application/x-www-form-urlencoded"
}
response = requests.post(url, data=payload, headers=headers)
# Проверка на ошибки HTTP
response.raise_for_status()
print(response.json())
get_keycloak_token()
Ответ сервера:
{
'access_token': hbG...L7A',
'expires_in': 60,
'refresh_expires_in': 1800,
'refresh_token': 'hbG...gcQ',
'token_type': 'Bearer',
'not-before-policy': 0,
'session_state': 'f...c',
'scope': 'profile email'
}
Если затем сформировать например get запрос к endpoint /admin/realms с заголовком Authorization Brearer <access_token> то будет доступ. Полный пример запроса:
import requests
BASE_URL = "http://192.168.1.195:9090"
def get_keycloak_token():
url = f"{BASE_URL}/realms/master/protocol/openid-connect/token"
payload = {
"grant_type": "password",
"client_id": "admin-cli",
"username": "admin",
"password": "admin",
}
headers = {
"Content-Type": "application/x-www-form-urlencoded"
}
response = requests.post(url, data=payload, headers=headers)
response.raise_for_status()
return response.json()["access_token"]
def get_realms(access_token: str):
url = f"{BASE_URL}/admin/realms"
headers = {
"Authorization": f"Bearer {access_token}"
}
response = requests.get(url, headers=headers)
response.raise_for_status()
return response.json()
if __name__ == "__main__":
try:
token = get_keycloak_token()
realms = get_realms(token)
print("Realms:")
for realm in realms:
print("-", realm.get("realm"))
except requests.HTTPError as e:
print("HTTP error:", e.response.text)
except Exception as e:
print("Unexpected error:", str(e))
Client registration
Параметры, которые будут применяться к пользователям, зарегистрированным в клиентах.
Раздел client scopes
Определяет данные и разрешения, получаемые клиентом в access token / через ID token при аутентификации пользователя. Взаимосвязь между атрибутами и scopes:

Маппер (Mapper) внутри Client Scope — это инструкция для Keycloak: «Возьми данные ОТСЮДА (атрибут, роль, контекст) и положи ИХ В ТОКЕН ПОД ТАКИМ ИМЕНЕМ».
Типы scope:
- Default: всегда включается в токен по умолчанию, даже если клиент не запрашивает его явно.
- Optional: будет включен в токен в случае явного запроса клиентом в параметре scope=... при авторизации.
- (Unassigned): не применяется клиенту вообще, пока его не назначат вручную или не укажут явно в токене.
Стандартные scopes:
| Название | Тип | Протокол | Назначение |
| acr | Default | OpenID Connect | добавляет в токен acr (Authentication Context Class Reference) - уровень аутентификации (например, MFA, пароль и т. д.). |
| address | Optional | OpenID Connect | добавляет адрес пользователя (address claim) в токен (если заполнено в профиле). |
| basic | Default | OpenID Connect | включает базовые claims - sub, name, preferred_username, given_name, family_name |
| Default | OpenID Connect |
добавляет email и email_verified в ID и Access токены |
|
| microprofile-jwt | Optional | OpenID Connect |
обеспечивает совместимость с Eclipse MicroProfile JWT - популярным стандартом для Java microservices |
| offline_access | Optional | OpenID Connect |
разрешает выдачу offline refresh token (живёт долго и используется без пользовательского взаимодействия). |
| role_list | Default | SAML |
включает список ролей (roles) пользователя в SAML assertions |
| roles | Default | OpenID Connect |
добавляет роли пользователя (realm roles и client roles) в access token (в realm_access.roles и resource_access) |
Также есть phone, profile
Добавление маппера:
Типы мапперов:
| Имя | Описание | |||||||||||||||||||||
| Allowed Web Origins |
Scope с данным mapper добавляет все разрешенные веб-источники к свойству "allowed-origins" в токене. Иначе это механизм копирования списка доверенных источников браузера из конфигурации Keycloak Client внутрь Access Token, чтобы бэкенд мог программно принять решение о разрешении CORS. При генерации токена он читает список разрешенных веб-источников, настроенный у Client (родителя этого Client Scope), и копирует этот список в указанный claim токена. Поля конфигурации маппера:
Пример: SPA (на http://localhost:3000) стучится на бэкенд (http://localhost:8080). Бэкенд получает токен, но как ему узнать, что JavaScript вашего фронта имеет право вызывать его API? Решение через маппер Allowed Web Origins:
Результат: Внутри Access Token появляется поле:
Теперь бэкенд:
Используется редко.
|
|||||||||||||||||||||
| Audience, Hardcoded claim, Audience Resolve | Решает вопрос "для кого этот токен" (Resource Server). Это поле aud (audience) в JWT токене. Оно указывает, какой ресурс (API/сервис) должен принять этот токен.
Зачем это нужно? Например, есть 3 микросервиса:
Если токен не имеет audience, любой сервис может принять токен, выданный для другого. Злоумышленник получает токен для payment-api, но пытается вызвать order-api. Без проверки aud — успешно. Решение: Keycloak добавляет в токен aud = "payment-api". order-api проверяет этот claim и отвергает токен (403 Forbidden).
Типы мапперов для Audience Audience (простой) Создаете маппер в Client Scope, указываете жестко имя аудитории. Конфигурация:
Результат: В access token появится "aud": ["payment-api"] Вручную claim aud с любым значением (массивом или строкой). Конфигурация:
Audience resolve (продвинутый) Автоматически собирает всех клиентов, которым был выдан токен, и добавляет их в aud. Например, если клиент spa-app запрашивает токен с scope, включающим audience-resolve маппер, в aud попадут все клиенты, на которые у пользователя есть доступ через service accounts. Реальный сценарий использования Сценарий: SPA + два микросервиса Настройка в Keycloak:
Процесс: // В токене: // SPA вызывает payment-api ✅ разрешено Сценарий: Токен для нескольких API Иногда нужно, чтобы один токен работал с несколькими сервисами: { Как сделать: Создаете маппер Hardcoded claim с массивом значений или используете несколько мапперов Audience. |
|||||||||||||||||||||
| Authentication Context Class Reference (ACR) |
Механизм указывающий способ (уровень или метод) аутентификации пользователя, а не просто факт. Claim acr.
Конфигурация маппера:
Алгоритм:
Приложение может запросить конкретный acr, и keycloak можно настроить на изменение способа авторизации. В токен попадает итоговый реальный acr. Реальные сценарии Сценарий 1: Разные уровни доверия для разных операций
Сценарий 2: Соответствие стандартам (eIDAS, NIST) Правительственные системы требуют определенные уровни аутентификации:
Сценарий 3: Корпоративная безопасность
Отличие ACR от AMR AMR (Authentication Methods Reference) — что использовали: пароль, OTP, WebAuthn. |
|||||||||||||||||||||
| Authentication Method Reference (AMR) |
Claim в JWT токене, который содержит массив строк, каждая из которых обозначает конкретный метод аутентификации, использованный пользователем во время входа.
RFC 8176 определяет стандартные значения AMR :
Keycloak позволяет использовать любые кастомные значения, не ограничиваясь стандартным списком.
Настройка в консоли администратора Настройка аутентификаторов:
Добавление маппера AMR:
Маппер автоматически соберет все выполненные аутентификаторы и добавит их в поле amr
|
|||||||||||||||||||||
| Claims parameter Token, Claims parameter with value ID Token |
Это НЕ маппер для добавления произвольных данных в токен из запроса. Это маппер для чтения OIDC Claims Parameter из запроса авторизации и добавления их в токен. встроенный в Keycloak маппер, который читает этот самый параметр claims из запроса авторизации и преобразует его в реальные claims в токене
Из остальных точек (headers, ...) данный элемент не считывается. Сценарий применения нишевый. Пример: необходимо, чтобы в ID token обязательно были email и phone_number, но только для этого конкретного запроса, а не для всех. Без маппера: пришлось бы создавать отдельный client scope и настраивать мапперы. С маппером: можно просто отправить правильный claims параметр.
В случае Claims parameter with value ID Token, добавляются именно в токен ID.
Параметр claims НЕ фильтрует claims, которые приходят из скоупов. Он добавляет дополнительные claims сверх того, что уже включено через scope. |
|||||||||||||||||||||
| Group Membership |
Берет группы, в которые входит пользователь в Keycloak, и записывает их названия в токен.
Настройка Создание маппера происходит в разделе Client Scopes или непосредственно в настройках Client: Clients → Client Scopes → выберите нужный scope (или создайте новый) Вкладка Mappers → Add mapper → By configuration Выберите Mapper Type → Group Membership
Best Practice:
|
|||||||||||||||||||||
| Map user group membership | Жестко запрограммированное утверждение | |||||||||||||||||||||
| Hardcoded Role | Жестко запрограммируйте роль в токене доступа. | |||||||||||||||||||||
| Nonce backwards compatible | Добавляет утверждение nonce в токен Access, Refresh и ID | |||||||||||||||||||||
| Organization Membership | Сопоставьте членство пользователя в организации | |||||||||||||||||||||
| Map user Organization membership | Попарный идентификатор субъекта | |||||||||||||||||||||
| Pairwise subject identifier | Вычисляет парный идентификатор субъекта, используя хэш-код sha-256, и добавляет его к заявке "sub". Смотрите спецификацию OpenID Connect для получения дополнительной информации о парных идентификаторах субъектов. | |||||||||||||||||||||
| Role Name Mapper | Сопоставьте назначенную роль с новым именем или позицией в токене. | |||||||||||||||||||||
| Session State | Добавьте запрос о состоянии сеанса (session_state) | |||||||||||||||||||||
| Subject (sub) | Добавьте запрос о предмете (под) | |||||||||||||||||||||
| User Address | Сопоставляет атрибуты адреса пользователя (улица, населенный пункт, регион, почтовый индекс и страна) с утверждением OpenID Connect "адрес". | |||||||||||||||||||||
| User Attribute | Сопоставляет пользовательский атрибут пользователя с утверждением токена. | |||||||||||||||||||||
| User Client Role |
Сопоставьте роль пользователя-клиента с заявкой на токен.
Когда Multivalued выключен, возвращаются только назначенные роли; когда включен — все существующие. |
|||||||||||||||||||||
| User Property | Сопоставьте встроенное свойство пользователя (адрес электронной почты, имя, фамилию) с заявкой на токен. | |||||||||||||||||||||
| User Realm Role |
Сопоставьте роль области пользователя с заявкой на токен.
Когда Multivalued выключен, возвращаются только назначенные роли; когда включен — все существующие. |
|||||||||||||||||||||
| User Session Note | Сопоставьте пользовательскую заметку о сеансе пользователя с заявкой на токен. | |||||||||||||||||||||
| User's full name | Сопоставляет имя и фамилию пользователя с заявкой OpenID Connect "имя". Формат <first> + ' ' + <last> |


No comments to display
No comments to display