От Hello World к Secure API: настраиваем Keycloak и Spring Security на Java
Салимжанов Р.Д.
Введение
В предыдущей статье мы подробно рассмотрели, что такое Keycloak и зачем его использовать для управления аутентификацией и авторизацией в приложениях. Мы также провели начальную настройку Keycloak, чтобы подготовить его к интеграции с нашими приложениями. Теперь пришло время перейти к более практическому аспекту и рассмотреть, как связка Keycloak и Spring Security может значительно упростить процесс аутентификации и авторизации в приложениях на базе Spring Boot.
Преимущества связки Keycloak + Spring Boot
Использование Keycloak в сочетании с Spring Boot предоставляет множество преимуществ:
- Упрощенная аутентификация: Keycloak позволяет легко настраивать различные методы аутентификации, включая OAuth2 и OpenID Connect, что делает процесс аутентификации более безопасным и гибким.
- Управление пользователями: Keycloak предоставляет мощные инструменты для управления пользователями, включая возможность создания ролей, групп и политик доступа, что упрощает администрирование.
- Интеграция с различными протоколами: Keycloak поддерживает множество протоколов аутентификации и авторизации, что позволяет легко интегрировать его с различными приложениями и сервисами.
- Масштабируемость: Использование Keycloak позволяет легко масштабировать ваше приложение, добавляя новые сервисы и обеспечивая единый механизм аутентификации.
- Безопасность: Keycloak обеспечивает высокий уровень безопасности благодаря поддержке современных стандартов и протоколов, а также возможности настройки многофакторной аутентификации.
В этой статье я предоставил готовый пример настройки аутентификации через Keycloak в приложении на Spring Boot. Вы увидите, как интегрировать Keycloak с Spring Security, настроить необходимые конфигурации и протестировать аутентификацию пользователей.
Подготовка окружения
В предыдущей статье мы подробно рассмотрели процесс установки Docker и настройки Keycloak с помощью docker-compose. Мы запустили Keycloak в контейнере, что позволило нам быстро развернуть сервер аутентификации без необходимости ручной установки. Теперь давайте кратко повторим основные шаги настройки Keycloak, которые нам понадобятся для интеграции с Spring Boot.
Вот как выглядит наш docker-compose.yml, который мы будем использовать для запуска Keycloak:
В этот раз мы сосредоточимся на базовой настройке без излишеств, без использования базы данных PostgreSQL и более сложных конфигураций, чтобы обеспечить простоту и доступность процесса.
Этот файл конфигурации создает контейнер с Keycloak, устанавливает учетные данные администратора и открывает порт 8080 для доступа к веб-интерфейсу Keycloak. После запуска контейнера вы сможете получить доступ к Keycloak по адресу http://localhost:8080 и продолжить настройку Realm, клиента и пользователей через веб-интерфейс.
Настройка Keycloak
Создание Realm
- Перейдите в веб-интерфейс Keycloak по адресу http://localhost:8080.
- Войдите с учетными данными администратора (admin/admin).
- На главной странице нажмите на кнопку " Create Realm".
- Введите имя (в моём случае test_realm) для нового Realm и нажмите "Create".
Создание Client
- Выберите созданный Realm в верхнем левом углу.
- Перейдите в раздел "Clients".
- Нажмите на кнопку "Create".
- Введите имя клиента (например, test_client).
- Нажмите "Save".
- В настройках клиента установите Client authentication ON, Authorization ON, Front channel logout ON, Backchannel logout session required ON, это база, далее настройку производите сами.
- Нажмите "Save".
Добавление пользователя и ролей
- Перейдите в раздел "Users".
- Нажмите на кнопку "Add User".
- Заполните необходимые поля (например, username, email) и нажмите "Save".
- Перейдите на вкладку "Credentials" и установите пароль для пользователя.
- Я создал testuser с паролем testuser
- Перейдите в раздел "Roles" и создайте необходимые роли, если они еще не созданы. (не обязательно, но желательно)
- Вернитесь к пользователю, выберите вкладку "Role Mappings" и назначьте созданные роли пользователю.
Создание Spring Boot приложения
Инициализация проекта
Перейдите на Spring Initializr (https://start.spring.io ) ну или инициализируйте через intellij idea.
Важные зависимости в pom.xml
Убедитесь, что в вашем pom.xml присутствуют следующие зависимости:
Настройка application.properties
Создайте или отредактируйте файл src/main/resources/application.properties и добавьте следующие настройки:
Здесь test_realm — это имя вашего Realm, созданного в Keycloak.
Тестовая настройка приложения
На этом этапе мы создадим три файла, которые помогут настроить аутентификацию и авторизацию в нашем Spring Boot приложении с использованием Keycloak. Эти файлы включают:
- TestController
- SecurityConfig
- KeycloakJwtAuthenticationConverter
Структура проекта
На этом этапе ваш проект должен выглядеть примерно следующим образом:
Теперь давайте подробнее рассмотрим каждый файл и его код.
1. TestController (REST-контроллер)
Назначение: Обработка HTTP-запросов и демонстрация работы аутентификации.
Что это такое?
Это контроллер с двумя примерами эндпоинтов:
- Публичный — доступен всем
- Защищенный — только для авторизованных
Как таблички на дверях:
- 🟢 "Зал для всех" (/public/hello)
- 🔒 "VIP-зал" (/hello)
Как это работает с SecurityConfig?
При запросе к /public/hello:
- SecurityConfig видит правило permitAll()
- Пропускает без проверки токена
При запросе к /hello:
- SecurityConfig требует аутентификацию
- Проверяет токен через Keycloak
- Если всё ок — пускает в "VIP-зал"
Что важно:
@RestController – помечает класс как контроллер REST API
@GetMapping – определяет обработчик GET-запросов
Разделение на /public/** (публичные) и защищенные эндпоинты
2. SecurityConfig (Конфигурация безопасности)
Назначение: Настройка правил безопасности и интеграция с Keycloak.
это набор правил, который говорит Spring Security:
- Какие URL защищать
- Как проверять права доступа
- Где брать информацию о пользователях
Представьте, что это инструкция для охранника на входе в клуб:
- Кого пускать без проверки (публичные зоны)
- Кого проверять по VIP-пропускам (токенам)
- Какие права должны быть у посетителей
Как работает?
Правила доступа (authorizeHttpRequests): /public/** — публичная зона, вход без токена, Все остальные URL (anyRequest()) требуют аутентификации.
Интеграция с Keycloak (oauth2ResourceServer): Используем JWT-токены для проверки, Подключаем кастомный конвертер для "перевода" ролей.
Ключевые элементы:
- @EnableWebSecurity – активирует механизм безопасности Spring
- .requestMatchers() – определяет правила доступа к URL
- .oauth2ResourceServer() – подключает OAuth2-сервер (Keycloak)
- .jwtAuthenticationConverter() – кастомная обработка JWT-токена
3. KeycloakJwtAuthenticationConverter (Конвертер JWT)
Назначение: Преобразование JWT-токена Keycloak в объект аутентификации Spring.
Зачем это нужно?
Представьте, что Keycloak отправляет вашему приложению JWT-токен, внутри которого есть список ролей пользователя. Но Spring Security "не понимает", где их искать, потому что Keycloak хранит роли в особом месте токена — в поле realm_access.roles.
Решение: Создаем конвертер, который:
· Берет стандартные права доступа (например, из scope).
· Добавляет роли из Keycloak.
· Переводит всё в формат, понятный Spring Security.
Как всё это работает вместе?
- Пользователь делает запрос
- SecurityConfig проверяет:
- Если URL в публичной зоне — пропускает сразуЕсли защищенный — требует токен
- KeycloakJwtAuthenticationConverter "переводит" роли из токена
- TestController возвращает ответ в зависимости от проверок
Итоговая аналогия
Представьте приложение как здание:
- SecurityConfig — книжка с правилами для охраны
- TestController — комнаты с разным уровнем доступа
- Keycloak — система выдачи пропусков
- Токен — электронный пропуск с чипом (JWT)
Тестирование
Теперь, когда мы настроили наше Spring Boot приложение и интегрировали его с Keycloak, давайте протестируем его функциональность. Мы проверим публичный эндпоинт, получим токен через Keycloak и протестируем защищенный эндпоинт с использованием этого токена. Также рассмотрим частые ошибки, которые могут возникнуть в процессе.
Перед тем как протестировать наше Spring Boot приложение, необходимо убедиться, что все компоненты правильно запущены. Сначала запушен докер а потом Spring Boot приложение.
Теперь, когда оба компонента запущены, вы можете протестировать их функциональность.
Например, в браузере проверим публичный эндпоинт и приватный:
Как мы видим публичный доступен, а приватный нет.
Для доступа к приватному эндпоинту нам необходимо использовать токен доступа, полученный через Keycloak. Однако браузер не поддерживает прямую передачу токена в заголовках, поэтому мы это сделаем через командную строку:
Для получения токена доступа через Keycloak вы можете использовать curl-запрос.
curl -X POST http://localhost:8080/realms/test_realm/protocol/openid-connect/token -H "Content-Type: application/x-www-form-urlencoded" -d "client_id=test_client&client_secret=bR4RDvBu8FGS4WdsgfdfgfTzEFS2n&username=testuser&password=testuser&grant_type=password"
client_secret=bR4RDvBu8FGS4Wb5Om9PiiOeKazEFS2n — секрет клиента, который также был сгенерирован в Keycloak. Чтобы узнать секрет клиента, Перейдите в раздел "Clients". Найдите и щелкните на имя клиента, для которого вы хотите узнать секрет (например, test_client). Перейдите на вкладку "Credentials" (Учетные данные). Здесь вы увидите поле "Secret" (Секрет), где будет указан ваш секрет клиента.
username=testuser — имя пользователя, для которого вы хотите получить токен.
password=testuser — пароль пользователя.
После выполнения этого запроса вы должны получить JSON-объект, содержащий access_token, который будет выглядеть примерно так:
Используйте полученный токен для доступа к защищенному эндпоинту:
curl -H "Authorization: Bearer YOUR_ACCESS_TOKEN" http://localhost:8081/hello
Вы должны получить ответ:
Hello, this is a secure endpoint!
Заключение
В этой статье мы успешно настроили защиту API для нашего Spring Boot приложения с помощью Keycloak. Вот основные итоги:
- Мы настроили аутентификацию через Keycloak. Публичные эндпоинты (/public/**) доступны всем, а защищенные эндпоинты требуют JWT-токен для доступа.
- Роли пользователей из Keycloak автоматически преобразуются в права доступа Spring Security, что упрощает управление доступом.
- Keycloak запускается в Docker-контейнере, что делает развертывание и настройку более простыми и удобными.
- Мы создали собственный конвертер ролей, который работает с данными Keycloak и совместим со Spring Security.
Таким образом, мы сделали простейшее тестовое приложение используя Keycloak с Spring Security.
СПИСОК ИСПОЛЬЗОВАННЫХ ИСТОЧНИКОВ
1) Keycloak Documentation. // [электронный ресурс]. URL: https://www.keycloak.org/documentation (дата обращения 22.01.2025).
2) Интеграция Keycloak в приложение Spring Boot 3 с использованием протокола OAuth2.0 // [электронный ресурс]. URL: https://habr.com/ru/companies/axenix/articles/780422/ (дата обращения 23.01.2025).
3) Безопасность REST API от А до ПИ // [электронный ресурс]. URL: https://habr.com/ru/articles/503284/ (дата обращения 23.01.2025).
4) deepseek.com // [электронный ресурс]. URL: https://chat.deepseek.com/a/chat/s/1e3767a7-4dec-4ce6-9a5f-d1d19b85351f (дата обращения 23.01.2025).
4) spring // [электронный ресурс]. URL: https://start.spring.io (дата обращения 23.01.2025).