Безопасная связь между службами между службами, работающими за Spring Cloud Gateway
У меня есть несколько микросервисов, работающих за облачным шлюзом Spring, и все микросервисы, работающие за ним, защищены протоколом OAuth2 с использованием сервера авторизации Spring. Все работает нормально, но мало кто из микросервисов хотел бы обмениваться данными друг с другом, но эти серверы ресурсов защищены.
Я создал зарегистрированный клиент (для каждой микрослужбы с собственным идентификатором клиента и секретом клиента) на сервере авторизации, а также соответствующую конфигурацию клиента OAuth2 для каждой службы. Я настроил эту настройку с помощью Webclient для получения данных из других служб, необходимых следующим образом.
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
SecurityFilterChain defaultFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(authorize -> authorize
.anyRequest().authenticated()
)
.oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt);
return http.build();
}
@Bean
public WebClient webClient(OAuth2AuthorizedClientManager authorizedClientManager) {
ServletOAuth2AuthorizedClientExchangeFilterFunction oauth2Client =
new ServletOAuth2AuthorizedClientExchangeFilterFunction(authorizedClientManager);
oauth2Client.setDefaultClientRegistrationId("server");
return WebClient.builder()
.apply(oauth2Client.oauth2Configuration())
.build();
}
@Bean
public OAuth2AuthorizedClientManager authorizedClientManager(
ClientRegistrationRepository clientRegistrationRepository,
OAuth2AuthorizedClientRepository authorizedClientRepository) {
OAuth2AuthorizedClientProvider authorizedClientProvider =
OAuth2AuthorizedClientProviderBuilder.builder()
.clientCredentials()
.build();
DefaultOAuth2AuthorizedClientManager authorizedClientManager = new DefaultOAuth2AuthorizedClientManager(
clientRegistrationRepository, authorizedClientRepository);
authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);
return authorizedClientManager;
}
....
....
application.yml (similar config. for resource-client2)
spring:
security:
oauth2:
client:
registration:
server:
scope: ROLE_RESOURCE_CLIENT1
client-id: resource-client1
client-secret: '{noop}secret1'
client-authentication-method: basic
authorization-grant-type: client_credentials
client-name: resource-client1-client-credentials
provider:
server:
token-uri: http://localhost:9001/oauth2/token
resourceserver:
jwt:
issuer-uri: http://localhost:9001
а на сервере авторизации конфигурация клиента следующая
private final static RegisteredClient resource1ServiceClient = RegisteredClient.withId("2")
.clientId("resource-client1")
.clientSecret("{noop}secret1")
.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
.authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS)
.build();
private final static RegisteredClient resource2ServiceClient = RegisteredClient.withId("3")
.clientId("resource-client2")
.clientSecret("{noop}secret2")
.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
.authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS)
.build();
когда я пытаюсь сделать остаточный вызов с помощью веб-клиента от ресурса client1 до ресурса client2, я получаю ошибку NPE, потому что сервер авторизации spring не предоставляет токен доступа. ошибка
java.lang.NullPointerException: Cannot invoke "org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse.getAccessToken()" because "tokenResponse" is null
at org.springframework.security.oauth2.client.ClientCredentialsOAuth2AuthorizedClientProvider.authorize(ClientCredentialsOAuth2AuthorizedClientProvider.java:87) ~[spring-security-oauth2-client-6.0.1.jar:6.0.1]
Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException:
Error has been observed at the following site(s):
*__checkpoint ⇢ Request to GET http://localhost:8082/hello2 [DefaultWebClient]
Original Stack Trace:
at org.springframework.security.oauth2.client.ClientCredentialsOAuth2AuthorizedClientProvider.authorize(ClientCredentialsOAuth2AuthorizedClientProvider.java:87) ~[spring-security-oauth2-client-6.0.1.jar:6.0.1]
at org.springframework.security.oauth2.client.DelegatingOAuth2AuthorizedClientProvider.authorize(DelegatingOAuth2AuthorizedClientProvider.java:71) ~[spring-security-oauth2-client-6.0.1.jar:6.0.1]
at org.springframework.security.oauth2.client.web.DefaultOAuth2AuthorizedClientManager.authorize(DefaultOAuth2AuthorizedClientManager.java:176) ~[spring-security-oauth2-client-6.0.1.jar:6.0.1]
at org.springframework.security.oauth2.client.web.reactive.function.client.ServletOAuth2AuthorizedClientExchangeFilterFunction.lambda$authorizeClient$22(ServletOAuth2AuthorizedClientExchangeFilterFunction.java:485) ~[spring-security-oauth2-client-6.0.1.jar:6.0.1]
at reactor.core.publisher.MonoSupplier.call(MonoSupplier.java:67) ~[reactor-core-3.5.1.jar:3.5.1]
Не уверен, что пошло не так с моей настройкой или не хватает логики, чтобы это сделать. с использованием последней весенней версии и весеннего сервера авторизации версии 1.0.0. Пожалуйста, помогите