title: Spring webclient : retry with a new token
body: <p>Using Spring Boot 2.5, I am trying to configure a webClient at the builder level that, when it gets a 401, will remove the current token and then try again to call the resource (so the webclient, realizing there's no token anymore, will fetch a new one before actually calling the resource).</p>
  <p>This is what I have so far :</p>
  <pre class="lang-java prettyprint-override"><code>  @Bean
    WebClient servletWebClient(ClientRegistrationRepository  clientRegistrations,
                        OAuth2AuthorizedClientRepository authorizedClients) {
  
      //this constructor  will configure internally a RemoveAuthorizedClientOAuth2AuthorizationFailureHandler,
      // and onAuthorizationFailure will be called on it when we get a 401
      var oauth = new ServletOAuth2AuthorizedClientExchangeFilterFunction(clientRegistrations, authorizedClients);
  
      oauth.setDefaultClientRegistrationId(&quot;keycloak&quot;);
  
      return WebClient.builder()
          .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
          .apply(oauth.oauth2Configuration())
          .build();
    }
  </code></pre>
  <p>I can see that when using this webClient, <code>RemoveAuthorizedClientOAuth2AuthorizationFailureHandler</code> comes into picture and <code>removeAuthorizedClient</code> is called. If I make a second call through this webClient, it automatically fetchs a new token before making the actual call.</p>
  <p>So now, I want to configure the retry part, and I was thinking an additional filter would do the trick :</p>
  <pre class="lang-java prettyprint-override"><code>  ExchangeFilterFunction retryOn401Function() {
  
      return (request, next) -&gt; next.exchange(request)
          .flatMap((Function&lt;ClientResponse, Mono&lt;ClientResponse&gt;&gt;) clientResponse -&gt; {
            if (clientResponse.statusCode().value() == 401) {
              log.warn(&quot;got an unauthorized status when calling service - will retry once&quot;);
              return next.exchange(request).retry(1L);
            } else {
              return Mono.just(clientResponse);
            }
          });
    }
  </code></pre>
  <p>and now the webClient is built with it :</p>
  <pre class="lang-java prettyprint-override"><code>    return WebClient.builder()
          .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
          .apply(oauth.oauth2Configuration())
           // filter added
          .filter(retryOn401Function())
          .build();
  </code></pre>
  <p>From what I can observe, the retry happens <strong>before</strong> <code>removeAuthorizedClient</code> is called. so the exact same call is retried, with the same token - which obviously fails again.</p>
  <p>I've seen a couple of similar questions, but the solutions feel &quot;hack-ish&quot; as it usually requires manipulating the headers myself in one way or another :</p>
  <ul>
  <li><a href="https://stackoverflow.com/a/64451287">https://stackoverflow.com/a/64451287</a></li>
  <li><a href="https://stackoverflow.com/a/68625592">https://stackoverflow.com/a/68625592</a></li>
  <li><a href="https://stackoverflow.com/a/50759253">https://stackoverflow.com/a/50759253</a> (older one)</li>
  </ul>
  <p>Surely, there must be a better &quot;Spring&quot; way to achieve this, right ? Is there a way for <code>removeAuthorizedClient</code> to be called before the retry ?</p>
  <p>Thanks !</p>