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/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *