Перейти к основному содержимому

Краткое руководство по использованию Keycloak с Spring Boot

· 8 мин. чтения

Задача: Медиана двух отсортированных массивов

Даны два отсортированных массива размерами n и m. Найдите медиану слияния этих двух массивов.
Временная сложность решения должна быть O(log(m + n)) ...

ANDROMEDA

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 , чтобы создать административный логин:

./f20b41efe57c0804bc0eac06a0bb6680.png

Давайте создадим начального пользователя-администратора с именем initial1 и паролем zaq1!QAZ . После нажатия кнопки « Создать » мы увидим сообщение « Пользователь создан » .

Теперь мы можем перейти к административной консоли. На странице входа мы введем начальные учетные данные администратора:

./44c4274e690dc6b02b277284ae762f90.png

3.2. Создание области

Успешный вход приведет нас к консоли и откроет для нас основную область по умолчанию.

Здесь мы сосредоточимся на создании пользовательской области.

Давайте перейдем в верхний левый угол , чтобы найти кнопку « Добавить область » :

./b8f93cacd714b13af4071fb047fef637.png

На следующем экране давайте добавим новую область под названием SpringBootKeycloak :

./aa2231f47a6805ec5460f37a28287aff.png

После нажатия кнопки « Создать » будет создана новая область, и мы будем перенаправлены на нее. Все операции в следующих разделах будут выполняться в этой новой области SpringBootKeycloak .

3.3. Создание клиента

Теперь мы перейдем на страницу «Клиенты». Как видно на изображении ниже, Keycloak поставляется с уже встроенными клиентами :

./1083328566858e5af7a2eb606eba3fb8.png

Нам все еще нужно добавить нового клиента в наше приложение, поэтому мы нажмем « Создать » . Мы назовем новое приложение Client login-app :

./4cbd8a57131cced2e49e706b8120a498.png

На следующем экране для целей этого руководства мы оставим все значения по умолчанию, кроме поля « Действительные URI перенаправления» . Это поле должно содержать URL-адреса приложений, которые будут использовать этот клиент для аутентификации :

./4237637099977939ab2c6c759908f647.png

Позже мы создадим приложение Spring Boot, работающее на порту 8081, которое будет использовать этот клиент. Поэтому мы использовали URL-адрес перенаправления http://localhost:8081/ * выше.

3.4. Создание роли и пользователя

Keycloak использует доступ на основе ролей; следовательно, у каждого пользователя должна быть роль.

Для этого нам нужно перейти на страницу Роли :

./91116172bf770d3309f80f81c9aa9505.png

Затем мы добавим роль пользователя :

./1814ca0bad501884fd28e7e4ff91256e.png

Теперь у нас есть роль, которую можно назначить пользователям, но поскольку пользователей пока нет, давайте перейдем на страницу « Пользователи » и добавим ее:

./59e2d4057481154a4268c98821210d02.png

Мы добавим пользователя с именем user1:

./4b4355bec991e3d8f963e098d61c48d8.png

После создания пользователя отобразится страница с его данными:

./390335cbd51fdc4e5a5ed50d38ebbe1f.png

Теперь мы можем перейти на вкладку Credentials . Мы установим начальный пароль на xsw2@WSX :

./64ec37e69305d791a44c482849f7563f.png

Наконец, мы перейдем на вкладку « Сопоставление ролей ». Мы назначим роль пользователя нашему user1 :

./f6c96cffca6e5b1f6a0b905bd3d3a57c.png

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 мы видим:

./a79b0adf2bde6761e97a3ce16905b738.png

Теперь мы нажимаем клиентов , чтобы войти в интрасеть, где находится конфиденциальная информация.

Обратите внимание, что мы были перенаправлены для аутентификации через Keycloak, чтобы узнать, авторизованы ли мы для просмотра этого контента:

./69621239f952e62238ef3b1258072315.png

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

./355ba5ac0482581c1c4218c5ad6fb476.png

Теперь мы закончили настройку подключения 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 .