← назад к разделу

БЕЗОПАСНОСТЬ И АВТОРИЗАЦИЯ Keycloak

Обязательно

Что такое Keycloak и зачем он нужен

IAM · SSO · OIDC

Отдельный сервер входа, который выдаёт токены приложениям и убирает самодельную систему паролей и SSO.

1. IAM управляет личностью и доступом

1 / 5

Регистрация, вход, восстановление, MFA, роли и федерация образуют отдельную инфраструктурную задачу.

  • Приложение не хранит пароли само.
  • Keycloak выступает Identity Provider.
  • Доступ к ресурсу остаётся у приложения.
Keycloak IAMlogin · MFA · rolesUsersApplications

2. SSO даёт один вход многим приложениям

2 / 5

Пользователь входит в IdP один раз, а приложения получают независимые токены и не видят пароль.

  • Backoffice и API используют общий IdP.
  • Logout и политика централизованы.
  • У каждого приложения свой client.
One loginKeycloakApp AApp B

3. OAuth2 выдаёт доступ, OIDC - личность

3 / 5

Access token подтверждает доступ к API, ID token описывает вход пользователя. Keycloak реализует оба протокола.

  • Resource server проверяет access token.
  • Client получает ID token.
  • Refresh обновляет доступ по правилам.
OIDCwho logged inOAuth2what can be accessedРазные токены и назначение

4. Realm изолирует пользователей и клиентов

4 / 5

Realm содержит собственных пользователей, роли, клиентов и ключи. Client описывает одно приложение.

  • Public client подходит браузеру с PKCE.
  • Confidential client хранит secret на сервере.
  • Мапперы добавляют роли в токен.
RealmUsers + rolesClient AClient B

5. Keycloak не заменяет доменную авторизацию

5 / 5

IdP подтверждает личность и роли, но владелец заказа и правила операции проверяются вашим приложением.

  • Middleware применяет роли.
  • ABAC проверяет ресурс.
  • Admin override пишет аудит.
KeycloakVerified principalDomain policyРоль известна, ресурсное право решает домен

Почти в каждом приложении есть вход: регистрация, пароль, кнопка «забыли пароль?», роли (обычный пользователь и админ). Кажется, что это пара экранов и одна таблица в базе. На деле за этими экранами прячется целый пласт работы, который очень легко сделать неправильно — а ошибка здесь означает дыру в безопасности. Keycloak — это готовый сервис, который берёт весь этот пласт на себя. Разберём с нуля и не торопясь: какую проблему он решает, что означают слова IAM и SSO, и где Keycloak стоит относительно вашего приложения и API.

Начнём с картинки: что меняется, когда вход переезжает из каждого приложения в отдельный сервис.

пять внутренних приложений компании: где живёт пароль было: в каждом приложении свой вход касса склад отчёты портал заявки пароли пароли пароли пароли пароли свой экран входа и своя таблица паролей — и так пять раз ошибка в проверке пароля живёт сразу в пяти местахуволился сотрудник — закрывать доступ в пяти системах стало: одна проходная, приложения ей доверяютсотрудникпарольKeycloakтокенкассаскладотчётыпорталзаявкиприложения пароль не видят — им приходит только токен блокировать и чинить вход теперь в одном месте размен на пяти приложениях:пароли лежат — былов 5 приложенияхпароли лежат — сталов 1 Keycloakподдерживать — было5 сервисовподдерживать — стало6 сервисов и база

Пароль перестаёт копироваться по приложениям: пять мест хранения превращаются в одно, и блокировать учётную запись достаточно в одном месте — правда, уже выданные токены доживают до конца своего срока. Плата за это — шестой сервис со своей базой, поэтому на единственном приложении размен не окупается.

Проблема: «напишу авторизацию сам»

Давайте честно посмотрим, что значит «сделать вход самому». Когда логин пишут руками, в проекте постепенно появляется такой список задач:

  • хранить пароли — но не сам пароль, а его хеш с солью, иначе при утечке базы утекут все пароли;
  • сделать регистрацию, вход, выход, смену пароля и сброс пароля по почте;
  • завести роли (кто обычный пользователь, кто администратор) и проверять права на каждой странице и в каждом запросе;
  • защититься от перебора паролей, от угона чужой сессии, от утечки токенов;
  • а потом, когда бизнес попросит, — добавить вход через Google, второй фактор (одноразовый код из приложения), блокировку учётной записи.

Каждый пункт по отдельности выглядит несложным. Беда в двух вещах. Первая: таких пунктов десятки, и ошибка в любом из них — это не «некрасивая кнопка», а уязвимость, через которую могут войти под чужим именем. Вторая: как только у вас появляется второе приложение, весь этот код приходится писать заново или копировать из проекта в проект — а вместе с кодом копируются и ошибки.

Вывод напрашивается сам: вход — это не «фича приложения», а отдельная самостоятельная задача. И раз она у всех одинаковая, логично взять готовое решение, а не изобретать своё.

Что такое Keycloak

Keycloak — это отдельный готовый сервис, которому вы передаёте всю работу со входом. Это бесплатный проект с открытым исходным кодом; его начинала Red Hat, а с 2023 года он развивается под крылом фонда CNCF. После подключения Keycloak ваше приложение перестаёт хранить пароли и заниматься входом. Оно лишь спрашивает у Keycloak один вопрос: «этот человек — кто, и что ему можно?»

Аналогия из жизни. Представьте бизнес-центр с десятком офисов. Раньше каждый офис держал на двери своего охранника, который проверял паспорта и вёл свой журнал посетителей. Это дорого, и охранники проверяют по-разному. Keycloak — это одна общая проходная на входе в здание. Вы один раз показываете документ на проходной, получаете пропуск-бейдж, и дальше ходите по офисам, показывая уже бейдж, а не паспорт. Офисы вообще не видят ваш паспорт — они доверяют проходной.

В этой аналогии:

  • проходная — это Keycloak;
  • паспорт — это ваш логин и пароль;
  • бейдж-пропуск — это токен, который выдаёт Keycloak;
  • офисы — это ваши приложения и сервисы.

IAM и SSO простыми словами

Вокруг Keycloak часто звучат две аббревиатуры — разберём их без жаргона.

IAM расшифровывается как Identity and Access Management — «управление личностями и доступом». Это общее название для всего, что отвечает на два вопроса: «кто это за человек» (личность, identity) и «что ему разрешено» (доступ, access). Keycloak — это IAM-система: он и хранит учётные записи, и решает, кому что можно. Когда говорят «у нас Keycloak как IAM», имеют в виду ровно это — единое место, где живут пользователи и их права.

SSO расшифровывается как Single Sign-On — «единый вход». Это удобство для пользователя: войти один раз и получить доступ сразу ко всем приложениям, не вводя пароль в каждом заново.

Поясним на боли. У компании пять внутренних приложений, и в каждом — свой экран входа. Сотрудник вводит пароль пять раз и держит в голове пять разных паролей. С SSO он входит один раз через Keycloak, а все приложения, подключённые к нему, узнают сотрудника автоматически. Единый выход из всех приложений тоже возможен, но сам собой не появляется: каждое приложение нужно научить слушать уведомление о выходе, а сервисы, работающие по токену, увидят изменение только когда токен истечёт. Это удобнее людям и безопаснее для компании: учётная запись одна, и если сотрудник уволился, заблокировать его можно в одном месте, а не бегать по пяти системам.

Связь простая: IAM — это про то, что Keycloak делает (управляет личностями и доступом). SSO — это одно из главных удобств, которое из этого вытекает (один вход на все приложения).

Где Keycloak стоит относительно приложения и API

Самое важное для понимания — где Keycloak находится в общей картине. Он стоит сбоку, отдельным сервисом, и через него проходит вход. Запомните ключевое разделение ролей:

  • Keycloak проверяет, кто пользователь (логин и пароль), и выдаёт ему «пропуск» — токены.
  • Ваше приложение пароль не проверяет вообще. Оно получает токен и проверяет только, что пропуск настоящий и не просрочен.
  • Ваш API (бэкенд, куда приложение ходит за данными) принимает токен в каждом запросе и по нему решает, отдавать данные или нет.

Дальше — что на схеме. Пользователь работает с приложением; приложение отправляет его залогиниться в Keycloak; Keycloak проверяет пароль и выдаёт токены обратно приложению; затем приложение ходит в защищённый API, прикладывая к каждому запросу заголовок Authorization: Bearer access_token — и API проверяет этот токен. Keycloak в центре как единый поставщик личности.

Пользователь вводит логин и пароль только в Keycloak, тот возвращает приложению токены, и приложение ходит в ваш API с заголовком Authorization: Bearer access_token

Обратите внимание на главное: стрелка с паролем идёт только в Keycloak. Ваш API пароль никогда не видит — он видит только токен. Это и есть смысл всей затеи: один сервис отвечает за вход, остальные ему доверяют по токену.

Что за «пропуск», который выдаёт Keycloak

Тот самый бейдж-пропуск из аналогии — это токен. Чаще всего Keycloak выдаёт его в формате JWT: это строка, внутри которой в читаемом виде лежат имя пользователя, его роли и срок годности, а в конце — цифровая подпись Keycloak. Приложение или API убеждается, что подпись настоящая, и после этого доверяет содержимому: «да, подпись Keycloak верна, значит это действительно роли этого человека».

Если совсем коротко, токенов на самом деле несколько, и у каждого своя роль:

  • access_token — главный «рабочий пропуск». Именно его приложение кладёт в заголовок Authorization: Bearer ... при обращении к API. По нему API понимает, кто пришёл и что ему можно.
  • id_token — отвечает на вопрос «кто именно вошёл» и предназначен для самого приложения, чтобы показать имя пользователя в интерфейсе. В API его не отправляют.
  • refresh_token — нужен, чтобы получить новый access_token, когда старый протух, не заставляя пользователя вводить пароль снова. Его отправляют только обратно в Keycloak.

Не пугайтесь, если пока не уложилось, — устройство токенов это отдельная большая тема (см. ссылки в конце). Здесь важна одна мысль: вход и проверка входа — это разные роли разных систем, а связывает их токен.

три токена ваш API access_token само приложение id_token обратно в Keycloak refresh_token

Видно, куда уходит каждый токен: в ваш API едет только access_token, id_token остаётся в самом приложении, а refresh_token возвращается туда, откуда пришёл.

Что Keycloak даёт из коробки

Главная ценность Keycloak — большой список готовых возможностей, которые иначе пришлось бы писать и поддерживать самому.

Единый вход (SSO)

Это мы уже разобрали выше: пользователь входит один раз, и все подключённые приложения узнают его без повторного ввода пароля. Единый выход — история отдельная: он не появляется сам по себе, каждое приложение придётся этому научить.

OAuth2 и OpenID Connect из коробки

Это два стандартных протокола — то есть общепринятые «правила разговора», по которым приложения и Keycloak договариваются о входе. Их ценность в том, что не нужно изобретать свой формат: Keycloak уже умеет говорить на общем языке, который понимают все.

  • OAuth2 отвечает на вопрос «что этому приложению разрешено делать от имени пользователя» — то есть про выдачу ограниченного доступа. Обратите внимание на формулировку: речь именно про приложение. Что можно самому человеку, решают уже роли и ваш код.
  • OpenID Connect (OIDC) — это надстройка над OAuth2, которая добавляет ответ на вопрос «кто это» — то есть про личность и сам факт входа. На практике для логина используют именно OIDC.

Почему это важно на практике: раз протоколы стандартные, к Keycloak без проблем подключаются и фронтенд на React, и мобильное приложение, и бэкенд на любом языке — все они понимают OAuth2/OIDC. Вы не привязаны к одной технологии и можете менять её части независимо.

Управление пользователями и ролями

В Keycloak есть готовый раздел администрирования — веб-интерфейс, где можно:

  • заводить и блокировать пользователей, сбрасывать им пароли;
  • создавать роли (например, customer, seller, admin) и назначать их людям;
  • объединять пользователей в группы для удобства;
  • настраивать политику паролей и второй фактор (одноразовый код).

И всё это — без единой строчки вашего кода. Роли, которые вы назначили человеку, Keycloak кладёт внутрь токена, а приложение по ним решает, что пользователю разрешено. Важный побочный плюс: управлять пользователями могут не программисты, а администраторы — через интерфейс, а не через правки в базе.

Вход через соцсети и подключение чужих систем

Federation (федерация) — это возможность пускать в приложение пользователей, которые хранятся не в самом Keycloak, а где-то ещё.

  • Social login — те самые кнопки «Войти через Google / GitHub / VK». Keycloak сам общается с этими сервисами по их правилам, а вам не нужно разбираться с каждым по отдельности.
  • Подключение корпоративного каталога — например, LDAP или Active Directory. Сотрудники входят под своими рабочими учётными записями, а Keycloak выступает посредником между вашим приложением и этим каталогом.

Принцип тот же, что и со всем остальным: разнообразие источников входа Keycloak прячет за собой, а вашему приложению отдаёт один понятный токен. Приложению вообще не важно, вошёл человек по паролю, через Google или по корпоративной учётке, — оно видит лишь токен.

И тут же появляется вопрос, который потом стоит дорого: где после подключения каталога находится источник правды о человеке. Keycloak каталог не проксирует, а импортирует пользователей к себе — у человека появляется запись в realm, и часть полей копируется из LDAP или от Google. Дальше начинаются расхождения: сотрудника переименовали в каталоге, а в realm остались старые данные; сотрудника уволили, а запись в realm ещё активна; ваш сервис завёл третью копию профиля в своей базе, потому что ему нужен телефон для курьера.

Боль снимает одно правило: у каждого поля один хозяин. Имя, должность и признак «работает или нет» приходят из каталога и в realm только копируются — значит, менять их в консоли Keycloak нельзя, и в настройках федерации для этого есть режим только для чтения. Пароль тоже остаётся в каталоге. А данные, которых в каталоге нет и не будет, живут в базе вашего сервиса и связываются с человеком по устойчивому идентификатору из токена (sub), а не по email, который меняется. Как быстро изменения в каталоге доезжают до сервисов — вопрос периодической синхронизации и срока жизни токена, и его разбирает статья про LDAP и Kerberos.

Из чего состоит Keycloak

Устройство простое. Есть сервер Keycloak — отдельное приложение (часто в контейнере), которое показывает пользователям страницы входа, проверяет пароли и выдаёт токены; ему нужна своя база данных для учётных записей и настроек. И есть административная консоль — веб-интерфейс того же сервера, через который заводят пользователей и роли, подключают приложения и соцсети.

Внутри сервера всё разложено по realm — изолированным пространствам, каждое со своими пользователями, ролями и списком подключённых приложений; приложение, зарегистрированное в realm, называется client. Что это такое и как их заводить — в статье про realm, client и роли.

Как приложение подключается к Keycloak

Подключение — это в основном настройка, а не код. Покажем общую картину на примере бэкенда: приложению достаточно сказать, где живёт Keycloak, и библиотека сама научится проверять токены.

В Spring Boot это одна настройка:

spring:
  security:
    oauth2:
      resourceserver:
        jwt:
          issuer-uri: https://keycloak.example.ru/realms/marketplace

В Go это go-oidc:

provider, err := oidc.NewProvider(ctx, "https://keycloak.example.ru/realms/marketplace")
verifier := provider.Verifier(&oidc.Config{ClientID: "marketplace-api"})

В NestJS это стратегия passport-jwt, которая берёт ключи по JWKS:

issuer: 'https://keycloak.example.ru/realms/marketplace',
secretOrKeyProvider: passportJwtSecret({
  jwksUri: 'https://keycloak.example.ru/realms/marketplace/protocol/openid-connect/certs',
  cache: true,
}),

В FastAPI это PyJWT с PyJWKClient:

jwks = PyJWKClient("https://keycloak.example.ru/realms/marketplace/protocol/openid-connect/certs", cache_keys=True)
claims = jwt.decode(token, jwks.get_signing_key_from_jwt(token).key, algorithms=["RS256"],
                    issuer="https://keycloak.example.ru/realms/marketplace")

Здесь адрес realm — это издатель (issuer). По нему библиотека сама находит публичные ключи Keycloak (их набор называется JWKS — набор ключей для проверки подписи) и дальше проверяет подпись каждого токена локально, не обращаясь к Keycloak на каждый запрос. Ключи скачиваются один раз и держатся в памяти; если Keycloak сменит ключ — библиотека подтянет новый автоматически. Это важно для скорости: пока ключи в памяти, проверка токена не зависит от того, доступен ли сейчас Keycloak.

Одна оговорка, чтобы не удивляться потом. За ключами библиотека обычно идёт не при старте приложения, а лениво — когда придёт первый запрос с токеном. Сервис поднимется, даже если Keycloak в этот момент лежит; но и первый токен тогда не проверится, пока Keycloak не вернётся.

Главная мысль остаётся прежней: логику входа писать не нужно — её уже написали в Keycloak. Ваша задача — указать адрес и доверять токенам, которые он подписал.

Потрогать за пять минут

Всё дальше в разделе проще понять, один раз получив токен своими руками. Keycloak поднимается одной командой в режиме разработки, без базы и TLS:

docker run --rm -p 8080:8080 \
  -e KC_BOOTSTRAP_ADMIN_USERNAME=admin -e KC_BOOTSTRAP_ADMIN_PASSWORD=admin \
  quay.io/keycloak/keycloak:26.0 start-dev

Через минуту на http://localhost:8080 открывается консоль администратора. Дальше четыре шага мышью. Создать realm shop (выпадающий список realm слева, «Create realm»). Создать client web-app: тип OpenID Connect, «Client authentication» выключен (это public client для фронтенда), в «Valid redirect URIs» поставить http://localhost:3000/*, в «Web origins» http://localhost:3000. Создать пользователя ivan и на вкладке «Credentials» задать ему пароль без пометки «temporary». И на клиенте временно включить «Direct access grants», чтобы получить токен из терминала без браузера:

curl -s -X POST http://localhost:8080/realms/shop/protocol/openid-connect/token \
  -d client_id=web-app -d grant_type=password -d username=ivan -d password=secret

В ответе JSON с access_token, refresh_token и сроками жизни. Вставьте access_token в любой разборщик JWT (локальный, а не публичный сайт, если это не стенд) и посмотрите claims: iss с адресом realm, sub, preferred_username, realm_access.roles, aud, exp. Это и есть тот «пропуск», о котором шла речь выше, и дальше статьи раздела объясняют каждое поле.

Два предупреждения. «Direct access grants» и пароль в curl это только для стенда: в настоящем приложении вход идёт через браузер по authorization code flow, и эту галочку выключают, о чём говорит чек-лист в статье про realm и client. И start-dev держит всё в памяти: остановили контейнер, realm исчез; для повторяемости realm экспортируют в файл и стартуют с --import-realm, об этом статья про эксплуатацию.

Цена владения: что придётся делать руками

«Ещё один сервис и база под него» — фраза, которая ничего не говорит о трудозатратах, а решают обычно именно по ним. Вот из чего складывается обслуживание.

Настройки надо уметь воспроизвести. Realm, клиенты, роли, мапперы и поток входа настраиваются мышью, и это ловушка: настроенный руками контур нельзя повторить. Лечится экспортом realm в файл и импортом при старте (--import-realm), а лучше описанием настроек как кода — есть keycloak-config-cli и провайдер для Terraform. Правило простое: если realm нельзя поднять с нуля одной командой, тестового контура у вас нет, есть только прод.

Резервная копия — это база, а не файлы. Пользователи, пароли, сессии и настройки живут в базе Keycloak, и её копируют как любую другую боевую базу. Отдельно берегут ключи подписи realm: потеряли базу вместе с ключами — все выданные токены разом стали недействительными, и это ещё мягкий исход.

Обновления с ломающими изменениями. Версии выходят часто, и мажорные переходы регулярно меняют имена настроек, поведение по умолчанию, вид консоли и административный API. Практика такая: читать примечания к выпуску до обновления, обновляться сначала на тестовом контуре из экспортированного realm и не отставать на годы — пять накопленных мажорных версий обновлять больнее, чем пять раз по одной.

Работа за обратным прокси. Самая частая беда первого запуска в проде: Keycloak строит адреса в редиректах и в поле iss из того, что видит сам, а видит он внутренний адрес контейнера. Снаружи он живёт как https://auth.example.ru, и об этом ему говорят явно настройкой KC_HOSTNAME, а доверие заголовкам прокси включают отдельно (KC_PROXY_HEADERS=xforwarded). Симптом, когда это забыли, узнаваемый: сервисы отвергают токены, потому что издатель в токене не совпадает с настроенным, а вход зацикливается на редиректах.

Отказоустойчивость. Keycloak — точка входа: пока он лежит, новых входов нет. При этом уже выданные токены продолжают работать, и сервисы проверяют подпись по ключам из памяти — то есть падение Keycloak ломает вход и обновление токенов, но не текущую работу. Отсюда и минимальная схема: два экземпляра за балансировщиком с общей базой и кэшем сессий в кластере.

Порядок величин для небольшой команды: несколько дней на первую нормальную настройку и несколько часов в квартал на обновления. Это не бесплатно, но и не отдельный проект — а вот «настроили мышью и забыли» обходится дороже всего.

Версии: почему старые инструкции не работают

Отдельная яма для новичка — поиск в интернете. До версии 17 Keycloak работал на сервере приложений WildFly, и там всё было иначе: запуск через standalone.sh, настройки в XML, свои переменные окружения и консоль по пути /auth. С 17-й версии он переехал на Quarkus, и с точки зрения эксплуатации это другое приложение: команда kc.sh start, настройки через переменные KC_* или параметры командной строки, консоль на корне без /auth.

Практический вывод: в найденном примере первым делом смотрят, нет ли в нём standalone.sh, XML-конфигурации или пути /auth. Если есть — это инструкция для старого Keycloak, и повторить её на нынешнем не получится, а сообщения об ошибках будут говорить совсем не о том. То же с библиотеками: старые адаптеры Keycloak для Spring (keycloak-spring-boot-starter, keycloak-spring-security-adapter) объявлены устаревшими и больше не поставляются, а их работу давно делает штатный spring-boot-starter-oauth2-resource-server — о нём статья про подключение Spring.

И деталь, которая экономит часы: версия в имени образа. quay.io/keycloak/keycloak:latest меняется под ногами, поэтому в рабочих файлах пишут точную версию, как и для любого другого образа.

Когда Keycloak нужен, а когда избыточен

Keycloak мощный, но не бесплатный по усилиям: это ещё один сервис, который надо запустить, обновлять и держать живым, плюс отдельная база под него. Поэтому решение «брать или не брать» зависит от масштаба.

Keycloak оправдан, когда:

  • приложений несколько и хочется один вход на всех (SSO);
  • нужен вход через соцсети, второй фактор или подключение к корпоративному каталогу;
  • пользователей и ролей много, и управлять ими должны администраторы, а не программисты;
  • безопасность входа критична и не хочется писать её самому.

Keycloak избыточен, когда:

  • проект маленький, приложение одно, пользователей десятки;
  • вход простой и без планов на соцсети и второй фактор;
  • нет ресурсов поддерживать ещё один сервис и базу под него.

Для маленького проекта отдельный сервер входа — это лишняя сложность: проще обойтись встроенными средствами вашего фреймворка. Keycloak начинает окупаться тогда, когда вход перестаёт быть «парой экранов» и становится самостоятельной задачей со своими требованиями.

«Встроенные средства фреймворка» для Spring означают форму входа и пользователей в своей базе: spring-boot-starter-security, таблица пользователей с ролями, пароли под медленным хешем, сессия в cookie. Такой вход занимает один класс конфигурации, отзывается мгновенно и не требует отдельного сервиса. Когда приложений станет больше одного, его меняют на Keycloak или на готовый провайдер — варианты перечислены в разделе про соседей по нише.

Дополнительно: при первом чтении можно пропустить

Глубже: второй фактор, политика паролей и защита от переборарасширенное

В списке «что даёт из коробки» эти три пункта стоят одной строкой, а включаются они в разных местах консоли, и по умолчанию выключены все три.

Политика паролей. Realm settings, вкладка «Authentication», раздел «Policies»: минимальная длина, запрет совпадения с именем пользователя и email, история (нельзя повторить последние N), срок действия, набор символов. Алгоритм хеширования выбирают там же: с версии 24 по умолчанию argon2, у старых realm может остаться pbkdf2, и его переключают, хеши пересчитываются при следующем входе каждого пользователя. Проверка по словарю утёкших паролей делается через required action или внешний провайдер.

Защита от перебора. Realm settings, «Security defenses», «Brute force detection»: выключена по умолчанию. Включают временную блокировку: после N неудачных попыток (обычно 5–10) учётная запись блокируется на растущее время, а не навсегда, потому что постоянная блокировка позволяет заблокировать любого пользователя, зная только его логин. Отдельный порог «quick login» ловит перебор быстрее человека. Блокировка по пользователю, а не по адресу: за NAT адрес общий на сотни человек. Что происходит при блокировке, видно на вкладке пользователя, и разблокировать можно вручную.

Второй фактор. Authentication, «Required actions»: Configure OTP включают как обязательное действие по умолчанию для новых пользователей или назначают отдельным пользователям и группам. Пользователь при следующем входе привязывает приложение-аутентификатор (TOTP, шесть цифр, тридцать секунд), и вход требует код. Политика OTP (тип, число цифр, окно) в той же вкладке. Без пароля вовсе умеет WebAuthn: ключ или биометрия устройства, и это отдельная политика и отдельный шаг в потоке входа. Условный второй фактор (только для админов, только с нового устройства) собирают в «Flows», копируя стандартный поток браузера и добавляя условие на роль.

Это относится к пользователям, которых Keycloak хранит сам. Для сотрудников из корпоративного каталога второй фактор часто остаётся на стороне каталога, о чём статья про LDAP и Kerberos.

Глубже: когда пароль всё же ваш: bcrypt, попытки и восстановлениерасширенное

Раздел про избыточность честно говорит: маленькому проекту хватит встроенных средств фреймворка. Тогда пароли хранит ваша база, и правил здесь немного, но нарушение любого из них это утечка всех паролей разом.

Хеш, а не шифрование, и медленный хеш. Пароль никогда не хранится и не шифруется обратимо: хранится результат медленной функции с солью. MD5, SHA-1 и даже SHA-256 не подходят: они быстрые, и утёкшую базу перебирают миллиардами вариантов в секунду. Подходят bcrypt с параметром стоимости 10–12, scrypt и argon2id, который сегодня рекомендуют первым. В Spring это Argon2PasswordEncoder.defaultsForSpringSecurity_v5_8() или BCryptPasswordEncoder, а обёртка DelegatingPasswordEncoder хранит имя алгоритма в самом хеше ({argon2}..., {bcrypt}...), и когда алгоритм захочется сменить, старые хеши распознаются и пересчитываются при следующем входе. Соль эти функции генерируют сами, отдельная колонка не нужна.

Попытки. Без ограничения перебор паролей идёт со скоростью вашего API. Счётчик неудач по учётной записи с растущей задержкой и временной блокировкой, лимит по адресу как вторая линия, и одинаковый ответ «неверный логин или пароль» на несуществующего пользователя и на неверный пароль, с одинаковым временем: проверка хеша занимает сотни миллисекунд, и для несуществующего пользователя её тоже выполняют, на фиктивном хеше, иначе по задержке видно, кого нет.

Восстановление доступа. Ссылка на смену пароля содержит одноразовый токен, случайный и длинный, в базе хранится его хеш со сроком в минуты, после использования запись удаляется, все сессии пользователя после смены пароля закрываются. Ответ на запрос восстановления не раскрывает, существует ли адрес. Секретные вопросы не используют: ответы на них ищутся быстрее паролей.

Всё это уже написано в Keycloak, и когда список выше начинает казаться длинным, это момент перечитать раздел про то, когда Keycloak оправдан.

Глубже: не только Keycloak: управляемые провайдеры и соседи по нишерасширенное

Развилка выше это «Keycloak или встроенные средства фреймворка», а на практике вариантов больше, и критерий выбора не «что мощнее», а «кто это будет обслуживать и где живут пользователи».

Управляемые провайдеры. Auth0, Okta, AWS Cognito, Microsoft Entra ID берут эксплуатацию на себя: обновления, отказоустойчивость, защита от перебора и второй фактор настроены. Плата по числу активных пользователей, а с российскими проектами добавляются доступность сервиса и требования локализации персональных данных по 152-ФЗ, из-за которых иностранный провайдер часто отпадает сразу.

Вход через российские учётные записи. Яндекс ID, VK ID, Сбер ID это провайдеры входа по OIDC для потребительских продуктов: пользователь входит своей учётной записью, а ваша система получает подтверждённый идентификатор и email. Это не замена Keycloak, а источник входа: в Keycloak их подключают как Identity Provider, и тогда SSO, роли и сессии остаются у вас, а пароли у провайдера. Для сервиса без своих ролей и без SSO между приложениями бывает достаточно подключить такой провайдер напрямую через Spring Security как OAuth2 client.

Соседи по нише, которые ставят у себя. Authentik проще в настройке и с более современным интерфейсом, силён как портал входа для внутренних инструментов. Zitadel написан на Go, изначально мультиарендный и хорошо ложится на продукты, где у каждого клиента своя организация с пользователями. Ory это набор отдельных сервисов (Kratos для учётных записей, Hydra для OAuth2) без интерфейса, который собирают под себя те, кому нужен полный контроль над экранами. Spring Authorization Server это библиотека, из которой сервер аутентификации пишут сами, и оправдан он, когда нужен один клиент и полная власть над кодом.

Критерий. Пользователи это сотрудники из корпоративного каталога, приложений много, нужен SSO: Keycloak или Authentik. Продукт для многих компаний-клиентов с их администраторами: Zitadel или Keycloak с realm на клиента. Потребительский продукт со входом через соцсети и без ролей: провайдер напрямую. Нет никого, кто будет обновлять сервер входа: управляемый провайдер, если 152-ФЗ позволяет. Keycloak остаётся выбором по умолчанию за расширяемость (SPI на любой шаг входа) и за то, что его умеют все, и это тоже аргумент.

Коротко

  • Keycloak — готовый сервис входа: хранит пользователей, проверяет пароли, выдаёт токены. IAM — управление личностями и доступом, SSO — один вход на все приложения.
  • Приложение и API получают подписанный токен и проверяют его локально по ключам JWKS, а пароль видит только Keycloak. access_token идёт в API, id_token остаётся в приложении, refresh_token возвращается в Keycloak.
  • Из коробки: OAuth2/OIDC, пользователи и роли, соцсети и корпоративные каталоги. Realm — изолированное пространство, client — запись о приложении. Подключение начинается с issuer-uri.
  • Keycloak оправдан при нескольких приложениях, соцсетях и втором факторе; одному маленькому проекту обычно хватает встроенных средств фреймворка. Альтернативы выбирают по тому, кто будет эксплуатировать сервер и где должны жить данные.
  • Цена владения: realm как код, резервные копии базы с ключами, обновления, настройки прокси и отказоустойчивость. С версии 17 используется Quarkus: старые инструкции с standalone.sh, XML и /auth не подходят.
  • Политика паролей, защита от перебора и второй фактор включаются отдельно. При федерации у каждого поля профиля один хозяин, а свои данные связывают по sub, а не по email.

Что почитать дальше