-
Notifications
You must be signed in to change notification settings - Fork 0
Description
@tlann I see the challenge that you are having. It's actually a bit tricky to get the OAuth2 WebClient working in the ScheduledAction. The issue here is that ServletOAuth2AuthorizedClientExchangeFilterFunction requires the current request HttpServletRequest and current Authentication in order for it to perform it's work. In your ScheduledAction, there is no current HttpServletRequest and therefore there is no current Authentication either.
The good news is that I managed to get this working for you either way.
Add the code below to your app.
@Configuration
public class WebClientConfig {
@Bean
WebClient webClient(ClientRegistrationRepository clientRegistrationRepository, OAuth2AuthorizedClientRepository authorizedClientRepository) {
ServletOAuth2AuthorizedClientExchangeFilterFunction oauth2 = new ServletOAuth2AuthorizedClientExchangeFilterFunction(
clientRegistrationRepository, authorizedClientRepository);
return WebClient.builder()
.apply(oauth2.oauth2Configuration())
.build();
}
@Bean
OAuth2AuthorizedClientRepository authorizedClientRepository(OAuth2AuthorizedClientService authorizedClientService) {
return new OAuth2AuthorizedClientRepository() {
final String DEFAULT_PRINCIPAL_NAME = "scheduled-client";
final Authentication DEFAULT_PRINCIPAL = new PrincipalNameAuthentication(DEFAULT_PRINCIPAL_NAME);
@Override
public <T extends OAuth2AuthorizedClient> T loadAuthorizedClient(String clientRegistrationId, Authentication principal, HttpServletRequest request) {
return authorizedClientService.loadAuthorizedClient(clientRegistrationId, DEFAULT_PRINCIPAL_NAME);
}
@Override
public void saveAuthorizedClient(OAuth2AuthorizedClient authorizedClient, Authentication principal, HttpServletRequest request, HttpServletResponse response) {
authorizedClientService.saveAuthorizedClient(authorizedClient, DEFAULT_PRINCIPAL);
}
@Override
public void removeAuthorizedClient(String clientRegistrationId, Authentication principal, HttpServletRequest request, HttpServletResponse response) {
authorizedClientService.removeAuthorizedClient(clientRegistrationId, DEFAULT_PRINCIPAL_NAME);
}
};
}
private static class PrincipalNameAuthentication implements Authentication {
private final String username;
private PrincipalNameAuthentication(String username) {
this.username = username;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
throw unsupported();
}
@Override
public Object getCredentials() {
throw unsupported();
}
@Override
public Object getDetails() {
throw unsupported();
}
@Override
public Object getPrincipal() {
throw unsupported();
}
@Override
public boolean isAuthenticated() {
throw unsupported();
}
@Override
public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException {
throw unsupported();
}
@Override
public String getName() {
return this.username;
}
private UnsupportedOperationException unsupported() {
return new UnsupportedOperationException("Not Supported");
}
}
}Then in your WebClientService.getVersion(), ensure to use the WebClient @Bean registered from the above config. This should work as I had it working in my local setup.
NOTE: As an FYI, for reactive apps, you would use ServerOAuth2AuthorizedClientExchangeFilterFunction for your WebClient instance.
Let me know how it goes.