Spring Boot WebClient OAuth2 client_credentials是否受支持?

时间:2019-04-28 20:49:37

标签: spring-boot spring-security spring-security-oauth2 spring-webflux

我正在尝试创建一个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

enter image description here

WebClient是否真的支持“ client_credentials” ...或者我缺少什么?

致谢

2 个答案:

答案 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);

Spring Security Reference

  

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)版本中,当令牌过期时会要求提供新令牌。

谢谢:)