Александр Есин / блог

Двухфакторный вход в Keycloak: как работает и где ломается

26 октября 2026

Прошлые посты были про то, откуда берутся данные о пользователе (федерация с AD, Kerberos) и как они попадают в токен. Теперь про второй фактор, потому что я про этот момент в прошлых постах забыл: где он хранится, как включается и почему иногда считается включённым, но не спрашивается.

Два слоя, которые постоянно путают

Двухфакторный вход в Keycloak — это две разные вещи:

  • Сценарий входа (Authentication → Flows) — порядок действий: кого спрашивать, что требовать, при каких условиях
  • Учётные данные пользователя (вкладка Credentials) — сам секрет: код в приложении, ключ безопасности, сертификат

Отсюда простое правило разбора: «второй фактор не спрашивают» — виноват сценарий. «Спрашивают, но не пускают» — виноваты данные или время.

Сценарий собирается из шагов. Шаги можно менять местами и помечать: обязательный, вариант на выбор, отключён. «Вариант на выбор» — значит подойдёт любой один. «Обязательный» — значит пройти нужно все по порядку. На этом и держится вся гибкость.

Что есть «из коробки»

  • Одноразовые коды по времени или по счётчику — обычное приложение-аутентификатор. Самый частый вариант
  • Ключи безопасности и встроенная биометрия (WebAuth)
  • Вход по клиентскому сертификату
  • Коды восстановления — резервный вход
  • Принудительная настройка: при следующем входе система требует настроить код

Чего нет: кодов по SMS, push-уведомлений, кодов на почту. Это всегда отдельное расширение — а значит, внешняя зависимость и новый набор возможных проблем.

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

Для всего realm задаётся: тип кода, алгоритм, число цифр, период действия, окно допуска по времени, счётчик.

Что важно понимать:

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

Не всем и не всегда

Главная конструкция — условный второй фактор: отдельный шаг с проверкой.

Условия из коробки:

  • Спрашивать, только если у человека уже настроен код
  • Спрашивать, только если у человека есть определённая роль

Второе и есть рабочий способ не навязывать второй фактор всем пяти тысячам сотрудников, а закрыть им админку, удалённый доступ и финансовые системы.

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

Повышение требований под конкретную систему

Сценарий: обычный вход — только пароль, но при заходе в критичный сервис нужно подтверждение.

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

Что нужно, чтобы заработало:

  • карта уровней защиты заполнена в настройках realm
  • сценарий умеет выдать нужный уровень
  • система действительно запрашивает этот уровень

Ключи безопасности: надёжнее, но сложнее

Для них задаётся отдельно: домен, допустимые адреса, требования к проверке пользователя.

Три решения, которые принимают до внедрения:

  • Домен фиксируется и не должен меняться. Переехали на другой адрес — все зарегистрированные ключи перестали работать
  • Нужен защищённый канал (HTTPS). Локально на своей машине работает, в тестовом контуре на обычном http — нет
  • Синхронизируемые ключи (passkeys) удобнее, но это уже иногда не второй фактор, а единственный.

SMS и другие каналы

Штатных кодов по SMS нет. Нужно готовое расширение или своя разработка.

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

Как сбросить

Способы не остаться без доступа:

  • Коды восстановления — выдаются заранее, человек хранит их сам
  • Сброс администратором — убрать код у пользователя в консоли, он настроит заново
  • Второй ключ — два устройства на одного человека

Если нет ни одного из трёх, то потерянный телефон = звонок в поддержку.

Как это связано с федерацией и AD

Важное и неочевидное:

  • Секрет для кодов живёт локально в Keycloak, а не в AD. Сброс пароля в каталоге второй фактор не затрагивает
  • Обратное тоже верно: требования к паролям в каталоге на второй фактор не влияют никак
  • Пересоздание пользователя (новый внутренний идентификатор) стирает его учётные данные. Тот же человек становится новым пользователем без кодов и без ключей

Проблемы и что с ними делать

1. Включено, но не спрашивается

Самое частое и самое опасное. Причины по убыванию частоты:

→ Отдельный клиент переопределяет сценарий своим. Один такой клиент без требования кода — и защита обойдена

→ Прямой обмен пароля на токен (без формы входа) сценарий не проходит вовсе. Мобильное приложение или скрипт получает токен без второго фактора

→ Вход через внешний источник идёт по своему сценарию первого входа. Если кода там нет, такие люди входят без второго фактора

→ Пользователь создан вручную, без требования настроить код

Что делать: проверить все входы и все сценарии, а не только основной.

2. Код верный, но не принимается

→ Часы. Код живёт по времени; расхождение больше окна — отказ. Проверить часы на телефоне, а не только на сервере

→ Настройки сменили, а секрет остался старый — нужен перевыпуск

→ Человек вводит код от другого аккаунта в том же приложении

3. «Неверные данные» сразу после настройки

→ Для кодов по счётчику: нажали «обновить» в приложении, не введя код, — счётчик разошёлся. Лечится сбросом и повторной настройкой

→ Для кодов по времени: окно допуска выставлено в ноль «для строгости»

4. Потеряно устройство

→ Заявка в поддержку

→ Сброс администратором

В общем это, наверное, пока финальный пост на эту тему.