是否支持 Spring Boot WebClient OAuth2 client_credentials?
Is Spring Boot WebClient OAuth2 client_credentials supported?
我正在尝试创建一个 Spring 启动 REST 应用程序,它必须对另一个 Spring 受 OAuth2 保护的启动应用程序进行远程 REST 调用(授权类型 client_credentials) .
第一个应用程序正在使用 Reactive WebClient 来调用第二个 OAuth2 REST 应用程序。
我已经用 grant_type "client_credentials" 配置了 WebClient(见下面的代码)
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);
}
但是每次我向第一个应用程序发出 Postman 调用时,我都会遇到以下异常:
"IllegalArgumentException: Invalid Authorization Grant Type (client_credentials) for Client Registration with Id: ..." 来自 DefaultOAuth2AuthorizationRequestResolver
WebClient 真的支持 "client_credentials" 吗...还是我遗漏了什么?
此致
- 第一个应用程序代码:
https://github.com/fdlessard/SpringBootOauth2WebClient
第二个应用代码:
https://github.com/fdlessard/SpringBootOAuth2Message
Spring引导版本 2.1.4
- spring-security-oauth2-client: 5.1.5.RELEASE
您必须使用 .apply(oauth.oauth2Configuration())
而不是 .filter(oauth)
,请参阅 ServletOAuth2AuthorizedClientExchangeFilterFunction
:
Provides an easy mechanism for using an OAuth2AuthorizedClient
to make OAuth2 requests by including the token as a Bearer Token. It also provides mechanisms for looking up the OAuth2AuthorizedClient
. This class is intended to be used in a servlet environment. Example usage:
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 Setup
The first step is ensuring to setup the WebClient correctly. An example of setting up WebClient in a servlet environment can be found below:
@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();
}
嗯,我终于可以让我的代码工作了。
... 是的,WebClient 确实支持带有 client_credential 的 OAuth2(部分)。
为了解决我的问题我必须禁用 oauth2 自动配置 并创建我自己的 WebSecurityConfigurerAdapter.
实现
我说 "partially" 的原因是因为 WebClient 的当前版本 spring 安全性 (5.1.x) 一旦令牌过期(对于客户端凭证)。只有 5.2.0.M2 或 (M1) 版本才会在令牌过期时请求新令牌。
谢谢:)
我正在尝试创建一个 Spring 启动 REST 应用程序,它必须对另一个 Spring 受 OAuth2 保护的启动应用程序进行远程 REST 调用(授权类型 client_credentials) .
第一个应用程序正在使用 Reactive WebClient 来调用第二个 OAuth2 REST 应用程序。
我已经用 grant_type "client_credentials" 配置了 WebClient(见下面的代码)
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);
}
但是每次我向第一个应用程序发出 Postman 调用时,我都会遇到以下异常:
"IllegalArgumentException: Invalid Authorization Grant Type (client_credentials) for Client Registration with Id: ..." 来自 DefaultOAuth2AuthorizationRequestResolver
WebClient 真的支持 "client_credentials" 吗...还是我遗漏了什么?
此致
- 第一个应用程序代码: https://github.com/fdlessard/SpringBootOauth2WebClient
第二个应用代码: https://github.com/fdlessard/SpringBootOAuth2Message
Spring引导版本 2.1.4
- spring-security-oauth2-client: 5.1.5.RELEASE
您必须使用 .apply(oauth.oauth2Configuration())
而不是 .filter(oauth)
,请参阅 ServletOAuth2AuthorizedClientExchangeFilterFunction
:
Provides an easy mechanism for using an
OAuth2AuthorizedClient
to make OAuth2 requests by including the token as a Bearer Token. It also provides mechanisms for looking up theOAuth2AuthorizedClient
. This class is intended to be used in a servlet environment. Example usage: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 Setup
The first step is ensuring to setup the WebClient correctly. An example of setting up WebClient in a servlet environment can be found below:
@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(); }
嗯,我终于可以让我的代码工作了。
... 是的,WebClient 确实支持带有 client_credential 的 OAuth2(部分)。
为了解决我的问题我必须禁用 oauth2 自动配置 并创建我自己的 WebSecurityConfigurerAdapter.
实现我说 "partially" 的原因是因为 WebClient 的当前版本 spring 安全性 (5.1.x) 一旦令牌过期(对于客户端凭证)。只有 5.2.0.M2 或 (M1) 版本才会在令牌过期时请求新令牌。
谢谢:)