Рубрики
Без рубрики

Как использовать Keycloak С приложением Spring Boot

В этом посте я покажу, как использовать Keycloak в приложении Spring Boot. Прежде чем мы используем Keycloak, w… Помеченный keycloak, springboot, java, spring security.

В этом посте я покажу, как использовать Keycloak в приложении Spring Boot. Прежде чем мы начнем использовать Keycloak, мы рассмотрим некоторые основы того, что такое Keycloak и почему мы его используем.

Чтобы начать работу с этой демонстрацией, вам понадобятся следующие вещи:

  • Редактор Кода – Интеллект
  • База данных – MySQL
  • Ключ-плащ
  • Java 8

Что такое Keycloak?

Keycloak – это решение для управления идентификацией и доступом с открытым исходным кодом для современных приложений и сервисов. Keycloak предоставляет решения как для протоколов SAML, так и для OpenID.

Почему мы используем Keycloak?

Как уже упоминалось, Keycloak обеспечивает управление идентификацией и доступом, он также является открытым исходным кодом. Протоколы SAML и OpenID являются отраслевыми стандартами. Создание приложения, интегрированного с Keycloak, только обеспечит вам более безопасное и стабильное решение. Безусловно, существуют и другие доступные решения, такие как Gluu, Shibboleth, WSO2.

Для этого поста мы будем использовать Keycloak.

Защита приложения Spring Boot с помощью Keycloak

В этой демонстрации есть две части. Один из них касается ключевого плаща. Второй касается защиты приложения Spring Boot с помощью Keycloak.

Установить Ключ-маскировку

Загрузите Keycloak на свой компьютер. Распакуйте загруженный файл и запустите сервер с помощью следующей команды из каталога bin в командной строке (Примечание – я на компьютере с Windows).:

Распакуйте загруженный файл и запустите сервер с помощью следующей команды из каталога bin в командной строке (Примечание – я на компьютере с Windows).:

Это запустит сервер Wildfly для вашего ключа на вашем локальном компьютере. Мы можем получить доступ к серверу, выполнив URL-адрес http://localhost:8180 . Если вы просто используете standalone.bat для выполнения без этого параметра, сервер будет работать на порту 8080 .

Как только вы запустите сервер, первое, что вам нужно будет сделать, это создать пользователя-администратора. Мы создадим имя пользователя admin и пароль d#n3q2b .

Теперь мы зайдем в консоль администрирования и введем ваши данные пользователя. Как только мы войдем в систему как пользователь-администратор, мы увидим первый экран, как показано ниже:

Добавление приложения

Начальный экран показывает область по умолчанию. Для наших демонстрационных целей мы создадим новую область SpringBootKeycloakApp . В этой области мы добавим наше приложение Spring Boot в качестве клиента. Создайте нового клиента на вкладке Клиенты. Мы назовем наше клиентское приложение приложением Spring Boot.

Теперь в настройках мы добавим URL-адрес перенаправления для нашего приложения Spring Boot. Это URL-адрес, по которому Keycloak перенаправит на наше приложение после аутентификации. Кроме того, мы используем openid connect в качестве протокола в рамках этой реализации.

Добавление Пользователя

Теперь мы добавим пользователя, которого будем использовать для аутентификации. Мы будем использовать этого пользователя для входа в наше примерное приложение Spring Boot.

Добавьте роль, которую вы хотите для этого пользователя ROLE_User на вкладке роли в Keycloak. Как только это будет сделано, давайте перейдем на вкладку “Пользователи” и добавим нового пользователя.

На вкладке Сопоставления ролей обязательно добавьте вновь созданную роль для этого пользователя.

Создайте Приложение Для Загрузки Spring

Теперь мы создадим простое приложение Spring Boot, которое будет использовать Keycloak для обеспечения безопасности. В рамках этого приложения мы будем показывать список задач списка дел для пользователя, который будет проходить аутентификацию с помощью приложения.

Для создания этого приложения нам нужны следующие зависимости:

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    implementation 'org.springframework.boot:spring-boot-starter-security'
    implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'org.springframework.boot:spring-boot-starter-jdbc'
    implementation 'org.keycloak:keycloak-spring-boot-starter'
    runtimeOnly 'mysql:mysql-connector-java'
    testImplementation('org.springframework.boot:spring-boot-starter-test') {
        exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
    }
    testImplementation 'org.springframework.security:spring-security-test'
}

Как вы можете видеть, мы используем spring-boot и spring-безопасность вместе с keycloak-spring-boot-starter зависимостью.

Зависимость keycloak включает в себя клиентские адаптеры Keycloak. Мы будем использовать эти адаптеры для целей аутентификации. Они заменят наши стандартные пружинные адаптеры безопасности. Чтобы убедиться, что эта зависимость keycloak-spring-boot-starter работает правильно, нам потребуется добавить еще одну зависимость в наш файл gradle, как показано ниже:

dependencyManagement {
    imports {
        mavenBom "org.keycloak.bom:keycloak-adapter-bom:11.0.2"
    }
}

Чтобы узнать больше об этом, вы можете посетить официальную документацию keycloak .

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

package com.betterjavacode.keycloakdemo.keycloakdemo.controllers;

import com.betterjavacode.keycloakdemo.keycloakdemo.dto.TaskDto;
import com.betterjavacode.keycloakdemo.keycloakdemo.managers.TaskManager;
import org.keycloak.KeycloakSecurityContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

import javax.servlet.http.HttpServletRequest;
import java.util.List;

@Controller
public class TaskController
{
    private final HttpServletRequest request;

    @Autowired
    public TaskController(HttpServletRequest request)
    {
        this.request = request;
    }

    @Autowired
    private TaskManager taskManager;

    @GetMapping(value="/")
    public String home()
    {
        return "index";
    }

    @GetMapping(value="/tasks")
    public String getTasks(Model model)
    {
        List tasks = taskManager.getAllTasks();
        model.addAttribute("tasks", tasks);
        model.addAttribute("name", getKeycloakSecurityContext().getIdToken().getGivenName());

        return "tasks";
    }

    private KeycloakSecurityContext getKeycloakSecurityContext()
    {
        return (KeycloakSecurityContext) request.getAttribute(KeycloakSecurityContext.class.getName());
    }

}

В этом классе контроллера мы используем Диспетчер задач для получения всех задач. Я объясню KeyCloakSecurityContext когда я покажу о SecurityConfig .

С пружинной защитой или без нее

Мы можем использовать это приложение и использовать Keycloak для аутентификации с или без Весна-Безопасность . В рамках этой демонстрации мы используем Spring-Security . Чтобы использовать то же приложение без Spring-Security, вы можете просто удалить зависимость Spring-Security и добавить конфигурацию безопасности через файл application.properties .

Нам понадобятся следующие свойства в application.properties , чтобы использовать Keycloak для аутентификации в этом приложении.

keycloak.auth-server-url=http://localhost:8180/auth
keycloak.realm=SpringBootKeycloakApp
keycloak.resource=SpringBootApp
keycloak.public-client=true
keycloak.principal-attribute=preferred_username

Если бы мы хотели использовать это приложение без Spring-Security, нам также понадобятся следующие два свойства:

keycloak.security-constraints[0].authRoles[0]=ROLE_User
keycloak.security-constraints[0].securityCollections[0].patterns[0]=/tasks

Поскольку мы используем Spring-Security , мы настроим конфигурацию безопасности с помощью класса Java SecurityConfig .

Этот класс SecurityConfig расширит Keycloak Web SecurityConfigurerAdapter .

Наш метод настройки будет выглядеть следующим образом:

    @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception
    {
        super.configure(httpSecurity);
        httpSecurity.authorizeRequests()
                .antMatchers("/tasks").hasRole("User")
                .anyRequest().permitAll();
    }

В принципе, любые запросы, поступающие на конечную точку/задачи, должны иметь роль пользователя как ROLE_User. Здесь предполагается префикс РОЛИ_. Кроме того, любой другой запрос будет разрешен без какого-либо разрешения. В этом случае мы будем называть нашу индексную страницу.

Мы будем использовать аннотацию @KeyCloakConfiguration , которая в основном охватывает @Конфигурация и @Включить веб-безопасность аннотации.

Так как наша конфигурация Безопасности расширяет KeycloakWebSecurityConfigurerАдаптер , мы должны реализовать sessionAuthenticationStrategy и httpsessionmanager. Нам также придется зарегистрировать наш идентификатор idp с помощью менеджера аутентификации Spring Security.

Таким образом, наша конфигурация безопасности будет выглядеть следующим образом:

package com.betterjavacode.keycloakdemo.keycloakdemo.config;

import org.keycloak.adapters.springsecurity.KeycloakConfiguration;
import org.keycloak.adapters.springsecurity.authentication.KeycloakAuthenticationProvider;
import org.keycloak.adapters.springsecurity.config.KeycloakWebSecurityConfigurerAdapter;
import org.keycloak.adapters.springsecurity.management.HttpSessionManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;

import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.core.authority.mapping.SimpleAuthorityMapper;
import org.springframework.security.core.session.SessionRegistryImpl;
import org.springframework.security.web.authentication.session.RegisterSessionAuthenticationStrategy;
import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy;


@KeycloakConfiguration
public class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter
{
    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder authenticationManagerBuilder)
    {
        SimpleAuthorityMapper simpleAuthorityMapper = new SimpleAuthorityMapper();
        simpleAuthorityMapper.setPrefix("ROLE_");

        KeycloakAuthenticationProvider keycloakAuthenticationProvider =
                keycloakAuthenticationProvider();
        keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(simpleAuthorityMapper);
        authenticationManagerBuilder.authenticationProvider(keycloakAuthenticationProvider);
    }

    @Bean
    @Override
    protected SessionAuthenticationStrategy sessionAuthenticationStrategy ()
    {
        return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl());
    }

    @Bean
    @Override
    @ConditionalOnMissingBean(HttpSessionManager.class)
    protected HttpSessionManager httpSessionManager()
    {
        return new HttpSessionManager();
    }

    @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception
    {
        super.configure(httpSecurity);
        httpSecurity.authorizeRequests()
                .antMatchers("/tasks").hasRole("User")
                .anyRequest().permitAll();
    }
}

Поэтому используйте роли пользователей Spring Security в верхнем регистре, такие как ROLE_USER, и всегда используйте префикс ROLE_. Чтобы справиться с этим, я добавил пользователя с ролью ROLE_User в Keycloak, но мы будем проверять только префикс, так как наша конфигурация http все равно будет проверять роль.

Поскольку мы будем проходить аутентификацию с помощью Keycloak, нам понадобится сеанс для состояния пользователя. Мы используем RegisterSessionAuthenticationStrategy здесь. HttpSessionManager является условным компонентом, потому что Keycloak уже реализует этот компонент.

Для реализации адаптера весенней загрузки Keycloak мы добавим Определитель конфигурации весенней загрузки KeyCloak компонент следующим образом:

package com.betterjavacode.keycloakdemo.keycloakdemo.config;

import org.keycloak.adapters.springboot.KeycloakSpringBootConfigResolver;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class KeycloakConfig
{
    @Bean
    public KeycloakSpringBootConfigResolver keycloakSpringBootConfigResolver()
    {
        return new KeycloakSpringBootConfigResolver();
    }
}

Я не показал остальную часть сборки приложения, но код доступен на GitHub для этого проекта.

Демонстрационная версия приложения

Запустите наше приложение keycloak, оно будет запущено на http://localhost:8180 . Наше приложение Spring Boot будет запущено по адресу http://localhost:8080 .

Наш первый экран приложения Spring Boot будет выглядеть следующим образом:

Теперь, если пользователь нажмет “Получить все задачи”, он будет перенаправлен на экран входа в систему Keycloak, как показано ниже:

Теперь я введу имя пользователя и пароль моего пользователя better java code, и он покажет нам наш список задач следующим образом:

Поток аутентификации

Когда пользователь нажимает “Получить все задачи”, пользователь перенаправляется на конечную точку входа/входа в систему Spring Security, которую обрабатывает Keycloakspringbootconfiguresolver и отправляет запрос на поток кода авторизации в Keycloak

http://localhost:8180/auth/realms/SpringBootKeycloakApp/protocol/openid-connect/auth?response_type=code&client_id=SpringBootApp&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Fsso%2Flogin&state=70bd4e28-89e6-43b8-8bea-94c6d057a5cf&login= истина и область применения= openid открытый идентификатор

Keycloak обработает запрос для ответа кодом сеанса и покажет экран входа в систему.

Как только пользователь введет учетные данные и keycloak подтвердит их, он ответит кодом авторизации, и этот код будет обменен на токен, и пользователь войдет в систему.

Вывод

В этом посте я показал, как защитить ваше приложение Spring Boot с помощью Keycloak в качестве поставщика удостоверений личности.

Оригинальное сообщение об этом было опубликовано в моем блоге лучший код java

Оригинал: “https://dev.to/betterjavacode/how-to-use-keycloak-with-a-spring-boot-application-3385”