Вопрос или проблема
Я currently working on a Spring Boot WebFlux application and would like to integrate Keycloak Policy Enforcer to enforce authorization policies defined in Keycloak.
Документация Keycloak предоставляет четкую поддержку для приложений на основе Servlet (Spring MVC), но я не нашел официальных указаний для WebFlux. Поскольку WebFlux является реактивным и использует ServerHttpSecurity вместо HttpSecurity, ServletPolicyEnforcerFilter, похоже, здесь не работает.
Существует ли способ интегрировать Keycloak Policy Enforcer с Spring Boot WebFlux? Если нет, какой будет рекомендуемый подход для реализации авторизационных политик (например, управление доступом на основе ролей или ресурсов) в приложении WebFlux с использованием Keycloak?
Буду признателен за любые примеры или идеи о том, как это можно реализовать!
Ответ или решение
Чтобы интегрировать Keycloak Policy Enforcer с приложением Spring Boot WebFlux, необходимо учитывать, что в отличие от традиционных Servlet-приложений, WebFlux требует другого подхода к обработке безопасности и авторизации. Поскольку Keycloak изначально ориентирован на работы с Servlet API (Spring MVC), его интеграция с реактивной моделью WebFlux требует дополнительных шагов. Вот направление, в котором вы можете двигаться.
Шаг 1: Настройка зависимости Keycloak
Первым делом, добавьте необходимые зависимости в ваш проект Spring Boot. Вам потребуется библиотека keycloak-spring-boot-starter
. Добавьте следующие зависимости в ваш файл pom.xml
:
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-spring-boot-starter</artifactId>
<version>XX.X.X</version> <!-- Убедитесь, что вы используете последнюю версию -->
</dependency>
Шаг 2: Настройка Keycloak
В файле application.properties
или application.yml
, добавьте настройки для подключения к вашему Keycloak-серверу:
keycloak.realm=myrealm
keycloak.auth-server-url=http://localhost:8080/auth
keycloak.ssl-required=external
keycloak.resource=myclient
keycloak.public-client=true
Шаг 3: Создание класса WebSecurityConfigurerAdapter
Поскольку WebFlux не использует HttpSecurity
, вместо этого мы будем настраивать безопасность через SecurityWebFilterChain
. Создайте класс конфигурации безопасности:
import org.keycloak.adapters.springsecurity.config.KeycloakWebSecurityConfigurerAdapter;
import org.keycloak.adapters.springsecurity.config.annotation.EnableKeycloak;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.web.server.SecurityWebFilterChain;
@Configuration
@EnableKeycloak
public class SecurityConfig {
@Bean
public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
http
.authorizeExchange()
.pathMatchers("/public/**").permitAll()
.anyExchange().authenticated()
.and()
.oauth2Login(); // Если вы используете OAuth2-авторизацию
return http.build();
}
}
Шаг 4: Реализация логики интеграции Policy Enforcer
Для применения политик доступа, определенных в Keycloak, вам потребуется создать кастомный фильтр или компонент. Рекомендуется использовать ReactiveSecurityContextHolder
для доступа к контексту безопасной сессии.
Пример:
import org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import reactor.core.publisher.Mono;
public class PolicyEnforcer {
public Mono<Void> enforcePolicy(ServerWebExchange exchange) {
KeycloakAuthenticationToken token = (KeycloakAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
// Используйте token для проверки политик
// Пример: проверка ролей
if (token.getAuthorities().contains(new SimpleGrantedAuthority("ROLE_USER"))) {
return Mono.empty(); // Доступ разрешен
} else {
return Mono.error(new AccessDeniedException("Доступ запрещен")); // Доступ запрещен
}
}
}
Шаг 5: Применение фильтра
Наконец, вам нужно вызвать метод enforcePolicy
в ваших контроллерах или сервисах для проверки доступа на основе политик Keycloak. Например:
@GetMapping("/protected")
public Mono<String> protectedResource(ServerWebExchange exchange) {
return policyEnforcer.enforcePolicy(exchange)
.then(Mono.just("Доступ к защищенному ресурсу"));
}
Заключение
Интеграция Keycloak Policy Enforcer с Spring Boot WebFlux требует немного больше настройки, чем с традиционным Spring MVC. Используя подход, описанный выше, вы сможете реализовать авторизацию с учетом политик, определенных в Keycloak. Обязательно протестируйте ваше приложение, чтобы убедиться, что все политики доступа применяются корректно.