1. Обзор
В этом руководстве мы рассмотрим основы настройки сервера Keycloak, подключения к нему приложения Spring Boot и использования его с Spring Security .
2. Что такое Keycloak?
Keycloak — это решение с открытым исходным кодом для управления идентификацией и доступом, предназначенное для современных приложений и сервисов.
Keycloak предлагает такие функции, как единый вход (SSO), посредничество в идентификации и вход через социальные сети, объединение пользователей, клиентские адаптеры, консоль администратора и консоль управления учетной записью. Чтобы узнать больше о Keycloak, посетите официальную страницу .
В нашем руководстве мы будем использовать консоль администратора Keycloak для настройки и подключения к Spring Boot с помощью клиентского адаптера Keycloak.
3. Настройка сервера Keycloak
3.1. Загрузка и установка Keycloak
Есть несколько дистрибутивов на выбор; однако в этом уроке мы будем использовать автономную версию.
Скачиваем серверный дистрибутив Keycloak -13.0.1 Standalone из официального источника.
После того, как мы загрузили дистрибутив Standalone server, мы можем разархивировать и запустить Keycloak из терминала:
unzip keycloak-13.0.1.zip
cd keycloak-13.0.1/bin
./standalone.sh -Djboss.socket.binding.port-offset=100
После запуска ./standalone.sh
Keycloak запустит свои службы. Как только мы увидим строку, содержащую Keycloak 13.0.1 (WildFly Core 15.0.1.Final)
, мы будем знать, что ее запуск завершен.
Теперь давайте откроем браузер и посетим http://localhost:8180 .
Мы будем перенаправлены на http://localhost:8180/auth
, чтобы создать административный логин:
Давайте создадим начального пользователя-администратора с именем initial1
и паролем zaq1!QAZ
. После нажатия кнопки « Создать
» мы увидим сообщение « Пользователь создан
» .
Теперь мы можем перейти к административной консоли. На странице входа мы введем начальные учетные данные администратора:
3.2. Создание области
Успешный вход приведет нас к консоли и откроет для нас основную
область по умолчанию.
Здесь мы сосредоточимся на создании пользовательской области.
Давайте перейдем в верхний левый угол , чтобы найти кнопку « Добавить область
» :
На следующем экране давайте добавим новую область под названием SpringBootKeycloak
:
После нажатия кнопки « Создать
» будет создана новая область, и мы будем перенаправлены на нее. Все операции в следующих разделах будут выполняться в этой новой области SpringBootKeycloak
.
3.3. Создание клиента
Теперь мы перейдем на страницу «Клиенты». Как видно на изображении ниже, Keycloak поставляется с уже встроенными клиентами :
Нам все еще нужно добавить нового клиента в наше приложение, поэтому мы нажмем « Создать
» . Мы назовем новое приложение Client login-app
:
На следующем экране для целей этого руководства мы оставим все значения по умолчанию, кроме поля « Действительные URI перенаправления» .
Это поле должно содержать URL-адреса приложений, которые будут использовать этот клиент для аутентификации :
Позже мы создадим приложение Spring Boot, работающее на порту 8081, которое будет использовать этот клиент. Поэтому мы использовали URL-адрес перенаправления http://localhost:8081/
* выше.
3.4. Создание роли и пользователя
Keycloak использует доступ на основе ролей; следовательно, у каждого пользователя должна быть роль.
Для этого нам нужно перейти на страницу Роли :
Затем мы добавим роль пользователя :
Теперь у нас есть роль, которую можно назначить пользователям, но поскольку пользователей пока нет, давайте перейдем на страницу « Пользователи
» и добавим ее:
Мы добавим пользователя с именем user1:
После создания пользователя отобразится страница с его данными:
Теперь мы можем перейти на вкладку Credentials .
Мы установим начальный пароль на xsw2@WSX
:
Наконец, мы перейдем на вкладку « Сопоставление ролей ».
Мы назначим роль пользователя
нашему user1
:
4. Генерация токенов доступа с помощью API Keycloak
Keycloak предоставляет REST API для создания и обновления токенов доступа. Мы можем легко использовать этот API для создания собственной страницы входа.
Во-первых, нам нужно получить токен доступа от Keycloak, отправив запрос POST на этот URL:
http://localhost:8180/auth/realms/SpringBootKeycloak/protocol/openid-connect/token
Запрос должен иметь это тело в формате x-www-form-urlencoded
:
client_id:<your_client_id>
username:<your_username>
password:<your_password>
grant_type:password
В ответ мы получим access_token
и refresh_token
.
Токен доступа следует использовать в каждом запросе к ресурсу, защищенному Keycloak, просто поместив его в заголовок Authorization :
headers: {
'Authorization': 'Bearer' + access_token
}
По истечении срока действия токена доступа мы можем обновить его, отправив запрос POST на тот же URL-адрес, что и выше, но содержащий токен обновления вместо имени пользователя и пароля:
{
'client_id': 'your_client_id',
'refresh_token': refresh_token_from_previous_request,
'grant_type': 'refresh_token'
}
Keycloak ответит на это новыми access_token
и refresh_token.
5. Создание приложения Spring Boot
5.1. Зависимости
Последние зависимости Spring Boot Keycloak Starter можно найти на Maven Central .
Адаптер Keycloak Spring Boot использует автоматическую настройку Spring Boot , поэтому все, что нам нужно сделать, это добавить стартер Keycloak Spring Boot в наш проект.
В XML-элементе зависимостей нам нужно следующее для запуска Keycloak с Spring Boot:
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-spring-boot-starter</artifactId>
</dependency>
После XML-элемента зависимостей нам нужно указать dependencyManagement
для Keycloak:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.keycloak.bom</groupId>
<artifactId>keycloak-adapter-bom</artifactId>
<version>13.0.1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
Следующие встроенные контейнеры теперь поддерживаются и не требуют дополнительных зависимостей при использовании Spring Boot Keycloak Starter:
- Кот
- Отлив
- пристань
5.2. Веб-страницы Тимелеафа
Мы используем Thymeleaf для наших веб-страниц.
У нас есть три страницы:
external.html —
общедоступная внешняя веб-страница.customers.html
— внутренняя страница, доступ к которой будет ограничен только авторизованными пользователями с рольюuser
.layout.html
— простой макет, состоящий из двух фрагментов, который используется как для внешней, так и для внутренней страницы.
Код шаблонов Thymeleaf доступен на Github .
5.3. Контроллер
Веб-контроллер сопоставляет внутренние и внешние URL-адреса с соответствующими шаблонами Thymeleaf:
@GetMapping(path = "/")
public String index() {
return "external";
}
@GetMapping(path = "/customers")
public String customers(Principal principal, Model model) {
addCustomers();
model.addAttribute("customers", customerDAO.findAll());
model.addAttribute("username", principal.getName());
return "customers";
}
Для пути /customers
мы извлекаем всех клиентов из репозитория и добавляем результат в качестве атрибута в модель
. Позже мы повторяем результаты в Thymeleaf.
Чтобы иметь возможность отображать имя пользователя, мы также внедряем принципала
.
Обратите внимание, что здесь мы используем клиента просто как необработанные данные для отображения, и не более того.
5.4. Конфигурация маскировки ключей
Вот базовая обязательная конфигурация :
keycloak.auth-server-url=http://localhost:8180/auth
keycloak.realm=SpringBootKeycloak
keycloak.resource=login-app
keycloak.public-client=true
Насколько мы помним, мы запускали Keycloak на порту 8180
, отсюда и путь, указанный в keycloak.auth-server-url
. Мы вводим имя области, которое мы создали, в консоли администратора Keycloak.
Значение, которое мы указываем в keycloak.resource
, соответствует клиенту, указанному в консоли администратора.
Вот ограничения безопасности, которые мы будем использовать:
keycloak.security-constraints[0].authRoles[0]=user
keycloak.security-constraints[0].securityCollections[0].patterns[0]=/customers/*
Эти ограничения гарантируют, что каждый запрос к /customers/*
будет авторизован только в том случае, если запрашивающий его является аутентифицированным пользователем с ролью user
.
Кроме того, мы можем определить keycloak.principal-attribute
как preference_username
, чтобы заполнить Principal
нашего контроллера подходящим пользователем:
keycloak.principal-attribute=preferred_username
5.5. Демонстрация
Теперь мы готовы протестировать наше приложение. Чтобы запустить приложение Spring Boot, мы можем легко запустить его через IDE, например Spring Tool Suite (STS), или запустить эту команду в терминале:
mvn clean spring-boot:run
При посещении http://localhost:8081
мы видим:
Теперь мы нажимаем клиентов
, чтобы войти в интрасеть, где находится конфиденциальная информация.
Обратите внимание, что мы были перенаправлены для аутентификации через Keycloak, чтобы узнать, авторизованы ли мы для просмотра этого контента:
Как только мы войдем в систему как user1
, Keycloak проверит нашу авторизацию, что у нас есть роль пользователя
, и мы будем перенаправлены на страницу ограниченных клиентов :
Теперь мы закончили настройку подключения Spring Boot с Keycloak и демонстрацию того, как это работает.
Как мы видим, Spring Boot без проблем справился со всем процессом вызова Keycloak Authorization Server . Нам не нужно было вызывать API Keycloak, чтобы самостоятельно сгенерировать токен доступа, или даже явно отправлять заголовок авторизации в нашем запросе на защищенные ресурсы.
Далее мы рассмотрим, как использовать Spring Security в сочетании с нашим существующим приложением.
6. Весенняя безопасность
Существует Keycloak Spring Security Adapter, и он уже включен в нашу зависимость Spring Boot Keycloak Starter . Теперь мы увидим, как интегрировать Spring Security с Keycloak.
6.1. Зависимость
Чтобы использовать Spring Security с Spring Boot, мы должны добавить эту зависимость:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
<version>2.6.1</version>
</dependency>
Последний релиз Spring Boot Starter Security можно найти на Maven Central .
6.2. Класс конфигурации
Keycloak предоставляет KeycloakWebSecurityConfigurerAdapter
в качестве удобного базового класса для создания экземпляра WebSecurityConfigurer
.
Это полезно, потому что для любого приложения, защищенного Spring Security, требуется класс конфигурации, который расширяет WebSecurityConfigurerAdapter:
@KeycloakConfiguration
class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter {
@Autowired
public void configureGlobal(
AuthenticationManagerBuilder auth) throws Exception {
KeycloakAuthenticationProvider keycloakAuthenticationProvider
= keycloakAuthenticationProvider();
keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(
new SimpleAuthorityMapper());
auth.authenticationProvider(keycloakAuthenticationProvider);
}
@Bean
@Override
protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
return new RegisterSessionAuthenticationStrategy(
new SessionRegistryImpl());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
super.configure(http);
http.authorizeRequests()
.antMatchers("/customers*")
.hasRole("user")
.anyRequest()
.permitAll();
}
}
В приведенном выше коде метод configureGlobal()
поручает SimpleAuthorityMapper
убедиться, что роли не имеют префикса ROLE_.
@Configuration
public class KeycloakConfig {
@Bean
public KeycloakSpringBootConfigResolver keycloakConfigResolver() {
return new KeycloakSpringBootConfigResolver();
}
}
Здесь keycloakConfigResolver
определяет, что мы хотим использовать поддержку файла свойств Spring Boot вместо keycloak.json по умолчанию.
Поскольку мы установили ограничения безопасности с помощью Spring Security, мы можем удалить или прокомментировать эти ограничения безопасности, которые мы разместили ранее в файле свойств:
#keycloak.security-constraints[0].authRoles[0]=user
#keycloak.security-constraints[0].securityCollections[0].patterns[0]=/customers/*
Теперь, после аутентификации, мы сможем получить доступ к внутренней странице клиентов, как и раньше.
7. Заключение
В этой статье мы настроили сервер Keycloak и использовали его с приложением Spring Boot.
Мы также узнали, как настроить Spring Security и использовать его вместе с Keycloak. Рабочая версия кода, показанного в этой статье, доступна на Github .