title: Spring Security 5.1 - Get Token for Client Credentials Flow with WebClient
body: <p>I am attempting to get a bearer token via a <code>webclient</code> with the following setup for an integration test of a secured resource server in a servlet application.</p>
  
  <pre><code>spring:
    security:
      oauth2:
        client:
          registration:
            idp:
              clientId: id
              clientSecret: secret
              authorization-grant-type: client_credentials
              scope: read
          provider:
            idp:
              authorization-uri: myidp/authorization.oauth2
              token-uri: myidp/token.oauth2
              user-info-uri: myidp/userinfo.openid
              user-name-attribute: name
  </code></pre>
  
  <p>And beans,</p>
  
  <pre><code>    @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(oauth.oauth2Configuration()).build();
      }
  </code></pre>
  
  <p>and autowiring the webclient to a test and calling it like so,</p>
  
  <pre><code>webClient.get().uri("http://localhost:" + port + "/web/it")
                  .attributes(ServletOAuth2AuthorizedClientExchangeFilterFunction.clientRegistrationId("idp")).retrieve()
                  .bodyToMono(String.class).block();
  </code></pre>
  
  <p>It is my assumption the exchange function would either get an access token if available, or do a call to get a new one from the IDP. However it will always fail as the <code>HttpSessionOAuth2AuthorizedClientRepository</code> as the <code>HttpServletRequest</code> is null.</p>
  
  <p>With the overall test looking like, this feeds into an autoconfiguration to configure some beans for an IDP provider.</p>
  
  <pre><code>@SpringBootTest(classes = WebITApplication.class,
          webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
  @ExtendWith(SpringExtension.class)
  @ActiveProfiles("web-it")
  class WebJwtIt {
  
      @LocalServerPort
      private int port;
  
      @Autowired
      private WebClient webClient;
  
      @Test
      void testIdpJwt() {
  
          String response = webClient.get().uri("http://localhost:" + port + "/web/it")
                  .attributes(ServletOAuth2AuthorizedClientExchangeFilterFunction.clientRegistrationId("ping")).retrieve()
                  .bodyToMono(String.class).block();
          assertThat(response).isEqualTo("pass");
      }
  
      @RestController
      @SpringBootApplication
      @ImportAutoConfiguration(IdpAutoConfiguration.class)
      static class WebITApplication implements IdpSecurityAdapter {
  
                @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(oauth.oauth2Configuration()).build();
      }
          public static void main(String args[]) {
  
              new SpringApplicationBuilder().profiles("web-it").build().run(WebITApplication.class, args);
          }
  
          @GetMapping
          public String secured() {
              return "secured";
          }
  
          @GetMapping("/web/it")
          public String securedOne() {
              return "pass";
          }
  
          @Override
          public void configure(final HttpSecurity httpSecurity) throws IdpSecurityAdapterException {
              try {
                  httpSecurity.oauth2Client();
              } catch (Exception e) {
                  throw new IdpSecurityAdapterException("Failed to Configure Oauth2Client", e);
              }
          }
  
          @Override
          public IdpProvider getIdpProvider() {
              return IdpProvider.MyIdp;
          }
      }
  </code></pre>
  
  <p>Is there anyway for a webclient to get the token for me and add it to the request? I know this was possible with the <code>spring-security-oauth:OAuthRestTemplate</code> and reading the documentation I thought it was possible with a web client.</p>