我正在尝试创建一个Spring Boot REST应用程序,该应用程序必须对另一个受OAuth2(授权类型为client_credentials)保护的Spring Boot应用程序进行远程REST调用。
第一个应用程序正在使用反应式WebClient 来调用第二个OAuth2 REST应用程序。
我已将WebClient配置为grant_type为“ client_credentials”(请参见下面的代码)
public WebClient messageWebClient(
ClientRegistrationRepository clientRegistrations,
OAuth2AuthorizedClientRepository authorizedClients,
ClientHttpConnector clientHttpConnector
) {
ServletOAuth2AuthorizedClientExchangeFilterFunction oauth =
new ServletOAuth2AuthorizedClientExchangeFilterFunction(clientRegistrations, authorizedClients);
oauth.setDefaultClientRegistrationId("message");
return WebClient.builder()
.baseUrl(MESSAGE_BASE_URL)
.clientConnector(clientHttpConnector)
.defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.defaultHeader(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE)
.filter(oauth)
.filter(logRequest())
.build();
}
@Bean
public ClientRegistrationRepository clientRegistrations() {
ClientRegistration clientRegistration = ClientRegistration
.withRegistrationId("message")
.clientId("client")
.clientSecret("secret")
.authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS)
.tokenUri("http://localhost:8081/oauth/token")
.build();
return new InMemoryClientRegistrationRepository(clientRegistration);
}
但是每次我对第一个应用程序进行邮递员呼叫时,都会遇到以下异常:
“ IllegalArgumentException:具有ID的客户端注册的无效授权授予类型(client_credentials):...” ,来自 DefaultOAuth2AuthorizationRequestResolver
WebClient是否真的支持“ client_credentials” ...或者我缺少什么?
致谢
第二个应用代码: https://github.com/fdlessard/SpringBootOAuth2Message
SpringBoot版本2.1.4
答案 0 :(得分:0)
您必须使用.apply(oauth.oauth2Configuration())
而不是.filter(oauth)
,请参阅ServletOAuth2AuthorizedClientExchangeFilterFunction
:
通过将令牌作为承载令牌提供,提供了一种使用
OAuth2AuthorizedClient
进行OAuth2请求的简单机制。它还提供了用于查找OAuth2AuthorizedClient
的机制。该类旨在在servlet环境中使用。用法示例:OAuth2AuthorizedClientExchangeFilterFunction oauth2 = new OAuth2AuthorizedClientExchangeFilterFunction(authorizedClientService); WebClient webClient = WebClient.builder() .apply(oauth2.oauth2Configuration()) .build(); Mono response = webClient .get() .uri(uri) .attributes(oauth2AuthorizedClient(authorizedClient)) // ... .retrieve() .bodyToMono(String.class);
13.1 WebClient OAuth2设置
第一步是确保正确设置WebClient。在servlet环境中设置WebClient的示例如下:
@Bean WebClient webClient(ClientRegistrationRepository clientRegistrations, OAuth2AuthorizedClientRepository authorizedClients) { ServletOAuth2AuthorizedClientExchangeFilterFunction oauth = new ServletOAuth2AuthorizedClientExchangeFilterFunction(clientRegistrations, authorizedClients); // (optional) explicitly opt into using the oauth2Login to provide an access token implicitly // oauth.setDefaultOAuth2AuthorizedClient(true); // (optional) set a default ClientRegistration.registrationId // oauth.setDefaultClientRegistrationId("client-registration-id"); return WebClient.builder() .apply(oauth2.oauth2Configuration()) .build(); }
答案 1 :(得分:0)
好吧,我终于能够使我的代码正常工作。
...,是的,WebClient确实支持带有client_credential的OAuth2(部分支持)。
要解决我的问题,我必须禁用oauth2自动配置,并创建自己的 WebSecurityConfigurerAdapter 实现。
我之所以说“部分”是因为,当前版本的WebClient春季安全性(5.1.x)不会在令牌过期(对于客户端证书)后要求新的令牌。仅在5.2.0.M2或(M1)版本中,当令牌过期时会要求提供新令牌。
谢谢:)