Expected Behavior
ServletOAuth2AuthorizedClientExchangeFilterFunction should have a way to set timeout.
Current Behavior
Current ServletOAuth2AuthorizedClientExchangeFilterFunction have no way to set timeout.
ServletOAuth2AuthorizedClientExchangeFilterFunction uses RefreshTokenOAuth2AuthorizedClientProvider, which has no way to set timeout to RestTemplate in its internal DefaultRefreshTokenTokenResponseClient .
Context
When an authorization server is slow or hanging, RestTemplate without timeout will block the thread.
Comment From: MasatoshiTada
Sorry, I found a way to set timeout. But, it's so verbose.
// Create RestTemplate with timeout
RestTemplate restTemplate = restTemplateBuilder
.setConnectTimeout(Duration.ofMillis(1000)) // configure timeout
.setReadTimeout(Duration.ofMillis(1000)) // configure timeout
.messageConverters(new FormHttpMessageConverter(),
new OAuth2AccessTokenResponseHttpMessageConverter())
.errorHandler(new OAuth2ErrorResponseErrorHandler())
.build();
// Create TokenResponseClient
DefaultRefreshTokenTokenResponseClient accessTokenResponseClient =
new DefaultRefreshTokenTokenResponseClient();
accessTokenResponseClient.setRestOperations(restTemplate);
// Create OAuth2AuthorizedClientProvider
OAuth2AuthorizedClientProvider authorizedClientProvider =
OAuth2AuthorizedClientProviderBuilder.builder()
.authorizationCode()
.refreshToken(refresh -> refresh.accessTokenResponseClient(accessTokenResponseClient))
.build();
// Create OAuth2AuthorizedClientManager
DefaultOAuth2AuthorizedClientManager authorizedClientManager =
new DefaultOAuth2AuthorizedClientManager(clientRegistrationRepository, authorizedClientRepository);
authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);
// Create RemoveAuthorizedClientOAuth2AuthorizationFailureHandler
OAuth2AuthorizationFailureHandler authorizationFailureHandler =
new RemoveAuthorizedClientOAuth2AuthorizationFailureHandler(
(clientRegistrationId, principal, attributes) ->
authorizedClientRepository.removeAuthorizedClient(clientRegistrationId, principal,
(HttpServletRequest) attributes.get(HttpServletRequest.class.getName()),
(HttpServletResponse) attributes.get(HttpServletResponse.class.getName())));
// Create ServletOAuth2AuthorizedClientExchangeFilterFunction
ServletOAuth2AuthorizedClientExchangeFilterFunction oAuth2Client =
new ServletOAuth2AuthorizedClientExchangeFilterFunction(authorizedClientManager);
oAuth2Client.setAuthorizationFailureHandler(authorizationFailureHandler);
I think Spring Security should have an easier way.
Comment From: jgrandja
@MasatoshiTada The custom configuration you outlined above is correct. I understand you feel it may be too verbose but as soon as you need to customize the underlying RestTemplate then this is the standard configuration.
If you didn't need to customize RestTemplate then you simply call the constructor ServletOAuth2AuthorizedClientExchangeFilterFunction(ClientRegistrationRepository, OAuth2AuthorizedClientRepository) and all the defaults are set for you.
There are a lot more configuration options available in RestTemplate other than read/connect timeout. And we couldn't expose all configuration options on our end since this would duplicate what's available in RestTemplateBuilder. We only expose setRestOperations() in the various OAuth2AccessTokenResponseClient implementations and it's up to the user to customize and set it accordingly.
I'm going to close this for the reasons outlined above.