Spring Cloud OpenFeign и авторизация (OAuth2). Ещё проще

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Несколько дней назад была поставлена задача сделать запросы между сервисами с токеном. У нас используется Keycloak в качестве SSO. В силу того, что нужно всё на базовом уровне (ничего специфического),то имеет смысл использовать Feign Client (OpenFeign) для Spring Boot.

Начал копаться в вопросе включения OAuth для Feign и через 1-2 дня наткнулся на только что опубликованную статью от @Kinski, но, как и везде, в ней и в других статьях есть некоторые неточности и даже в той же документации. Опишу различные варианты включения, которые я счёл верными и простыми с некоторым описанием.

В нашем случае client.registration у нас keycloak.
Spring Boot 2.7.6
Spring Cloud 2021.0.5

1. Включаем OAuth2 для всех Feign клиентов

Первая неточность по документации - это параметры включения как раз этого OAuth для Feign. Вместо настроек для Spring

spring:
  cloud:
    openfeign:
      oauth2:
        enabled: true
        clientRegistrationId: keycloak

которые ничего не включат.

  1. надо использовать

feign:
  oauth2:
    enabled: true
    clientRegistrationId: keycloak

естественно подключаем пакеты:
- spring-boot-starter-security
- spring-boot-starter-oauth2-client
- spring-cloud-starter-openfeign.

  1. Далее включаем сам OAuth2Client security

public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    http
        // ваши настройки +
        .oauth2Client();
    return http.build();
}
  1. ну и прописываем настройки для OAuth2 клиента

spring:
  security:
    oauth2:
      client:
        registration:
          keycloak:
            client-id: id вашего клиента для провайдера
            client-secret: ваш секрет
            authorization-grant-type: client_credentials
            provider: keycloak
        provider:
          keycloak:
            token-uri: адрес до провайдера токена

После этого все запросы через Feign Client будут обогощаться OAuth токеном.

2. Включаем OAuth2 только для нужных Feign клиентов

Повторяем из 1го раздела пункты 3 и 4. Далее создаём конфигурацию для Feign

public class OAuthFeignConfig {
    private final OAuth2ClientProperties oAuth2ClientProperties;

    public OAuthFeignConfig(OAuth2ClientProperties oAuth2ClientProperties) {
        this.oAuth2ClientProperties = oAuth2ClientProperties;
    }

    @Bean
    @ConditionalOnBean({OAuth2AuthorizedClientService.class, ClientRegistrationRepository.class})
    @ConditionalOnMissingBean
    public OAuth2AuthorizedClientManager feignOAuth2AuthorizedClientManager(ClientRegistrationRepository clientRegistrationRepository,
            OAuth2AuthorizedClientService oAuth2AuthorizedClientService) {
        return new AuthorizedClientServiceOAuth2AuthorizedClientManager(clientRegistrationRepository, oAuth2AuthorizedClientService);
    }

    @Bean
    @ConditionalOnBean(OAuth2AuthorizedClientManager.class)
    public OAuth2AccessTokenInterceptor defaultOAuth2AccessTokenInterceptor(OAuth2AuthorizedClientManager oAuth2AuthorizedClientManager) {
        return new OAuth2AccessTokenInterceptor(oAuth2ClientProperties.getRegistration().keySet().iterator().next(), oAuth2AuthorizedClientManager);
    }
}

Фактически код создания бинов скопирован из исходников и поправлен только в моменте прописывания имени клиентской регистрации из настроек.
В раскопках помогли исходники:

  • FeignAutoConfiguration from org.springframework.cloud.openfeign

  • OAuth2AccessTokenInterceptor from org.springframework.cloud.openfeign.security

В 19й строке использовал oAuth2ClientProperties.getRegistration().keySet().iterator().next() для получения первой в списке регистрации (чтобы не хардкодить. У нас это keycloak).
теперь в любом нашем FeignClient дописываем конфигурацию:

@FeignClient(value = "client-name", url = "your_url", configuration = OAuthFeignConfig.class)

PS: статья первая,сильно не бейте. Решил оформить после статьи от @Kinskiс более детальным описанием и раскрытием нюансов, которые на просторах интернета не описаны нигде.
Если кому-то статья сократит время разработки и поможет - буду рад!

Источник: https://habr.com/ru/post/719934/


Интересные статьи

Интересные статьи

В этой статье мы рассмотрим подход, при котором разработка приложений ведется непосредственно в кластере Kubernetes, а отдельные операции сборки и деплоя оказываются не нужны. Такую возможность предос...
Рецепт легкого перекуса для «Telegram - монстра Франкенштейна»Всем привет, это вторая часть создания телеграмм-бота (ссылка на первую часть), в ней мы реализуем Kafka Consumer, который будет ловить л...
Sweetviz — это библиотека Python с открытым исходным кодом, которая генерирует отчеты с удобной визуализацией для выполнения EDA с помощью всего двух строк кода. Библиоте...
В 2019 году люди знакомятся с брендом, выбирают и, что самое главное, ПОКУПАЮТ через интернет. Сегодня практически у любого бизнеса есть свой сайт — от личных блогов, зарабатывающих на рекламе, до инт...
Один из самых острых вопросов при разработке на Битрикс - это миграции базы данных. Какие же способы облегчить эту задачу есть на данный момент?