How to get accesstoken from WebClient like in RestTemplate?

Viewed 2579

I was going through the Spring Security Oauth 2.x migration to Spring security 5.2 and encountered the following blocker. As I can see OAuth2RestTemplate is not used anymore, instead WebClient is recommended. So i was making changes to my codebase to make webclient work.

In Oauth2 we have an option to get token straight from RestTemplate using oAuth2RestTemplate.getAccessToken(), i couldn't find anything similar in WebClient. This is to call an external microservice. Is there any option to get the accesstoken from webclient? Or is it handled in a different way there?

1 Answers

As usual when working with spring security, a lot of stuff happens automagically with configuration by convention. Meaning: you should get familiar with the oauth-related spring security configuration.

A good starting point for your studies will be the spring security docu or one of the many good Baeldung articles on this topic (maybe this one helps: https://www.baeldung.com/spring-oauth-login-webflux).

With the correct configuration in place, the following method will create a WebClient that has the proper oauth token automatically created on demand in the filter method.

In this case a Bean of type ReactiveOAuth2AuthorizedClientManager takes care of this. That bean is created in listing no. 2.

Furthermore, you need to configure the oauth server url and the credentials. See Listing 3 for a simple example.

This example works without you needing to handle the access token.


    @Bean
    public WebClient oauthWebClient(
        final WebClient.Builder webClientBuilder,
        @Qualifier("authorizedClientManager") final ReactiveOAuth2AuthorizedClientManager manager) {
        final ExchangeStrategies exchangeStrategies =
            ExchangeStrategies.builder()
                              .codecs(configurer -> configurer.defaultCodecs().maxInMemorySize(EXCHANGE_BYTE_COUNT))
                              .build();
        final ServerOAuth2AuthorizedClientExchangeFilterFunction oauth = new ServerOAuth2AuthorizedClientExchangeFilterFunction(manager);
        oauth.setDefaultClientRegistrationId(authenticationProperties.getClientId());
        // set more properties if needed
        // oauth.set ...

        return webClientBuilder
            .exchangeStrategies(exchangeStrategies)
            .baseUrl(apiProperties.getBaseUrl())
            .filter(oauth)
            .build();
    }

Listing 1: create a WebClient bean

    @Bean
    public ReactiveOAuth2AuthorizedClientManager authorizedClientManager(
        final ReactiveClientRegistrationRepository clientRegistrationRepository,
        final ReactiveOAuth2AuthorizedClientService authorizedClientService) {
        final ReactiveOAuth2AuthorizedClientProvider authorizedClientProvider =
            ReactiveOAuth2AuthorizedClientProviderBuilder
                .builder()
                .clientCredentials()
                .build();
        final AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager authorizedClientManager =
            new AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager(clientRegistrationRepository, authorizedClientService);
        authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);
        return authorizedClientManager;
    }

Listing 2: create an OAuth2 authorized client manager bean

spring:
  security:
    oauth2:
      resourceserver:
        jwt:
          issuer-uri: https://your-oauth-server.com/auth/realms/your-realm
      client:
        provider:
          your-provider:
            issuer-uri: https://your-oauth-server.com/auth/realms/your-realm
        registration:
          your-provider:
            client-id: your-client-id
            client-secret: ${your_client_secret} # from an environment variable
            scope: openid
            authorization-grant-type: client_credentials

Listing 3: one of many possible ways to configure your spring web client

Related