Keycloak
Keycloak является сервером, а не страницей, в которую ты встраиваешь скрипт, поэтому Caputchin поставляется как расширение Keycloak: provider-JAR, который ты добавляешь в Keycloak. Оно рендерит виджет Caputchin на страницах входа, сброса пароля и регистрации и проверяет токен изнутри Keycloak, прежде чем поток продолжится. Работают и виджет-галочка, и игра.
Расширение с открытым исходным кодом. Полная справка (каждое свойство конфигурации, JSON экспорта realm, контракт темы и матрица совместимости) живёт в репозитории: github.com/Caputchin/caputchin-keycloak. Рассчитывай примерно на 15 минут от нового аккаунта до первой проверенной на сервере сессии.
Работает с Keycloak 26.x (дистрибутив Quarkus). Тебе нужен доступ к развёртыванию Keycloak, чтобы добавить provider-JAR и выполнить kc.sh build, а также аккаунт администратора realm, который ты защищаешь.
1. Создай ключ сайта
Войди на caputchin.com/login (первый вход создаёт аккаунт), открой свою команду Личная, нажми Создать ключ сайта, назови его по имени своего realm Keycloak и нажми Создать. Скопируй оба значения:
- публичный ключ (
cpt_pub_...), - секрет (
cpt_sec_...). Он показывается только один раз.
Руководство Создай аккаунт и первый ключ сайта проводит по тем же экранам подробнее.
2. Установи расширение
Скачай caputchin-keycloak.jar из последнего релиза, скопируй его в каталог providers/ Keycloak и пересобери:
cp caputchin-keycloak.jar "$KEYCLOAK_HOME/providers/"
"$KEYCLOAK_HOME/bin/kc.sh" build
"$KEYCLOAK_HOME/bin/kc.sh" start --optimizedkc.sh build нужен, чтобы Keycloak обнаружил провайдеры. В образе контейнера скопируй JAR и выполни сборку в самом образе:
FROM quay.io/keycloak/keycloak:26.4
COPY caputchin-keycloak.jar /opt/keycloak/providers/
RUN /opt/keycloak/bin/kc.sh buildЕсли хочешь собрать JAR из исходников, смотри руководство по установке в репозитории.
3. Передай Keycloak секрет
Не держи секрет в конфигурации realm: задай его как переменную окружения на сервере Keycloak, например CAPUTCHIN_SECRET, и перезапусти Keycloak. На шаге 5 ты вводишь только имя переменной. Подходят и секрет в виде литерала, и ссылка ${vault.*}; смотри руководство по конфигурации в репозитории.
4. Выбери, как рендерится виджет
Есть два способа, и ты выбираешь для каждого realm.
Под ключ: встроенная тема
JAR несёт тему входа caputchin. В Admin Console открой свой realm, перейди в Realm settings → Themes, поставь в Login theme значение caputchin и нажми Save. Виджет рендерится на страницах входа, сброса и регистрации без правки шаблонов. Это самый быстрый путь, если ты используешь стандартный вход Keycloak.
Headless: твоя собственная тема рендерит виджет
Если ты поставляешь собственную тему входа (например, React-тему Keycloakify), сохрани свою тему и запусти расширение в headless-режиме. Оно открывает конфигурацию виджета в контекст страницы и валидирует токен; твоя тема рендерит элемент <caputchin-widget> (или <caputchin-game>). Поле токена называется caputchin-token. Полный контракт атрибутов и пример Keycloakify есть в руководстве по теме в репозитории.
5. Привяжи его к потоку входа
Keycloak не меняет аутентификатор шага на месте, поэтому ты добавляешь шаг Caputchin в копию потока и удаляешь исходный шаг.
-
Перейди в Authentication. У потока browser открой меню (⋮), нажми Duplicate, назови копию (например,
browser caputchin) и нажми Duplicate. -
В копии найди под-поток forms. Нажми его кнопку + (Add), выбери Add execution, выбери Caputchin Username Password Form и нажми Add.
-
Перетащи новый шаг в начало под-потока forms, выше под-потока Conditional 2FA, чтобы он выполнялся там же, где выполнялся старый шаг. Его требование: Required.
-
Удали исходный шаг Username Password Form из под-потока forms.
-
Нажми шестерёнку (Settings) у шага Caputchin и заполни:
- Alias: любое имя, например
caputchin-login. - Site key: твой публичный ключ (
cpt_pub_...), единственное значение, отправляемое в браузер. - Secret key env var: имя переменной из шага 3, например
CAPUTCHIN_SECRET.
Затем нажми Save. У остальных полей рабочие значения по умолчанию: Widget mode
checkbox(илиinvisible, илиgame), Localekc(следует locale realm) и включённый Fail closed, так что сбой проверки блокирует входы, а не пропускает их. - Alias: любое имя, например
-
Открой меню Action потока, нажми Bind flow, оставь Browser flow и нажми Save.
Испытание рендерится на той же странице, что и учётные данные, а не как отдельный шаг. С настройками по умолчанию проверка запускается, когда пользователь нажимает Sign In.
Сброс пароля и регистрация
Тот же приём защищает две другие формы:
| Поток | Добавь этот шаг | Вместо |
|---|---|---|
| Reset credentials | Caputchin Reset Credential - Choose User | Choose User |
| Registration | Caputchin в под-потоке формы регистрации, с требованием Required | (добавляется рядом с Registration User Creation) |
У каждого шага Caputchin свои настройки (шестерёнка), так что вводи ключ сайта и переменную секрета в каждом. Не добавляй испытание в поток direct grant: там нет браузера, так что это сломало бы запросы токенов по API. Раздел Привязка к потокам в репозитории показывает ту же настройку в виде JSON экспорта realm.
Более богатый вид (какая игра, скины, бренд) задаётся один раз в панели Caputchin на самом ключе сайта, так что в Keycloak ты его не повторяешь.
6. Проверь Content Security Policy
Стандартная Content Security Policy входа Keycloak (в Realm settings → Security defenses → Headers) выглядит так: frame-src 'self'; frame-ancestors 'self'; object-src 'none';. Она ограничивает фреймы, а не скрипты или соединения, а игра запускается во фрейме srcdoc, поэтому галочка, невидимый виджет и игра работают с ней без изменений.
Если ты задаёшь собственную, более строгую политику, начни с той, что приведена в руководстве по CSP в репозитории. Директива script-src действует и на собственные встроенные скрипты Keycloak, поэтому после любого изменения проверь страницу входа и Account Console.
Проверка на стороне сервера (Keycloak к хосту проверки) представляет собой вызов сервер-к-серверу, и браузерная политика на неё не влияет.
7. Подтверди первую проверенную на сервере сессию
- Открой вход своего приложения (или страницу входа realm) в приватном окне.
- Войди под тестовым пользователем. Виджет запускается, когда ты нажимаешь Sign In, и Keycloak впускает тебя.
- В панели Caputchin открой свою команду и нажми на свой ключ сайта. Обнови статистику.
Проверено на сервере теперь показывает как минимум 1: Keycloak подтвердил токен у Caputchin. Это твоя первая проверенная сессия. Если страница входа показывает "Verification failed. Please complete the check and try again.", а Проверено на сервере остаётся на 0, значит токен так и не дошёл до Keycloak: поищи в консоли браузера ошибку Content Security Policy (шаг 6). Если Пройдено в браузере выросло, а вход всё равно не удаётся, проверь, что переменная секрета из шага 3 задана на сервере. Статистика и сессии объясняет каждое число.
Попробуй локально
Репозиторий включает локальный Keycloak в одну команду (e2e/), связанный с локальным стеком Caputchin, чтобы ты мог прокликать все три защищённых потока перед развёртыванием. Смотри README репозитория.