1
0
mirror of synced 2026-08-04 01:07:02 +00:00

WebClient OAuth2 Support for defaultClientRegistrationId

Fixes: gh-5872
This commit is contained in:
Rob Winch
2018-09-19 11:27:56 -05:00
parent f48055ce47
commit dcbf762a0b
8 changed files with 103 additions and 4 deletions
@@ -55,6 +55,8 @@ class OAuth2AuthorizedClientResolver {
private boolean defaultOAuth2AuthorizedClient;
private String defaultClientRegistrationId;
public OAuth2AuthorizedClientResolver(
ReactiveClientRegistrationRepository clientRegistrationRepository,
ServerOAuth2AuthorizedClientRepository authorizedClientRepository) {
@@ -75,6 +77,15 @@ class OAuth2AuthorizedClientResolver {
this.defaultOAuth2AuthorizedClient = defaultOAuth2AuthorizedClient;
}
/**
* If set, will be used as the default {@link ClientRegistration#getRegistrationId()}. It is
* recommended to be cautious with this feature since all HTTP requests will receive the access token.
* @param clientRegistrationId the id to use
*/
public void setDefaultClientRegistrationId(String clientRegistrationId) {
this.defaultClientRegistrationId = clientRegistrationId;
}
/**
* Sets the {@link ReactiveOAuth2AccessTokenResponseClient} to be used for getting an {@link OAuth2AuthorizedClient} for
* client_credentials grant.
@@ -92,6 +103,7 @@ class OAuth2AuthorizedClientResolver {
.switchIfEmpty(currentAuthentication());
Mono<String> defaultedRegistrationId = Mono.justOrEmpty(clientRegistrationId)
.switchIfEmpty(Mono.justOrEmpty(this.defaultClientRegistrationId))
.switchIfEmpty(clientRegistrationId(defaultedAuthentication));
Mono<Optional<ServerWebExchange>> defaultedExchange = Mono.justOrEmpty(exchange)
@@ -188,6 +188,15 @@ public final class ServerOAuth2AuthorizedClientExchangeFilterFunction implements
this.authorizedClientResolver.setDefaultOAuth2AuthorizedClient(defaultOAuth2AuthorizedClient);
}
/**
* If set, will be used as the default {@link ClientRegistration#getRegistrationId()}. It is
* recommended to be cautious with this feature since all HTTP requests will receive the access token.
* @param clientRegistrationId the id to use
*/
public void setDefaultClientRegistrationId(String clientRegistrationId) {
this.authorizedClientResolver.setDefaultClientRegistrationId(clientRegistrationId);
}
/**
* Sets the {@link ReactiveOAuth2AccessTokenResponseClient} to be used for getting an {@link OAuth2AuthorizedClient} for
* client_credentials grant.
@@ -121,6 +121,8 @@ public final class ServletOAuth2AuthorizedClientExchangeFilterFunction implement
private boolean defaultOAuth2AuthorizedClient;
private String defaultClientRegistrationId;
public ServletOAuth2AuthorizedClientExchangeFilterFunction() {}
public ServletOAuth2AuthorizedClientExchangeFilterFunction(
@@ -152,6 +154,16 @@ public final class ServletOAuth2AuthorizedClientExchangeFilterFunction implement
this.defaultOAuth2AuthorizedClient = defaultOAuth2AuthorizedClient;
}
/**
* If set, will be used as the default {@link ClientRegistration#getRegistrationId()}. It is
* recommended to be cautious with this feature since all HTTP requests will receive the access token.
* @param clientRegistrationId the id to use
*/
public void setDefaultClientRegistrationId(String clientRegistrationId) {
this.defaultClientRegistrationId = clientRegistrationId;
}
/**
* Configures the builder with {@link #defaultRequest()} and adds this as a {@link ExchangeFilterFunction}
* @return the {@link Consumer} to configure the builder
@@ -295,6 +307,9 @@ public final class ServletOAuth2AuthorizedClientExchangeFilterFunction implement
Authentication authentication = getAuthentication(attrs);
String clientRegistrationId = getClientRegistrationId(attrs);
if (clientRegistrationId == null) {
clientRegistrationId = this.defaultClientRegistrationId;
}
if (clientRegistrationId == null
&& this.defaultOAuth2AuthorizedClient
&& authentication instanceof OAuth2AuthenticationToken) {
@@ -55,6 +55,8 @@ class OAuth2AuthorizedClientResolver {
private boolean defaultOAuth2AuthorizedClient;
private String defaultClientRegistrationId;
public OAuth2AuthorizedClientResolver(
ReactiveClientRegistrationRepository clientRegistrationRepository,
ServerOAuth2AuthorizedClientRepository authorizedClientRepository) {
@@ -75,6 +77,15 @@ class OAuth2AuthorizedClientResolver {
this.defaultOAuth2AuthorizedClient = defaultOAuth2AuthorizedClient;
}
/**
* If set, will be used as the default {@link ClientRegistration#getRegistrationId()}. It is
* recommended to be cautious with this feature since all HTTP requests will receive the access token.
* @param clientRegistrationId the id to use
*/
public void setDefaultClientRegistrationId(String clientRegistrationId) {
this.defaultClientRegistrationId = clientRegistrationId;
}
/**
* Sets the {@link ReactiveOAuth2AccessTokenResponseClient} to be used for getting an {@link OAuth2AuthorizedClient} for
* client_credentials grant.
@@ -92,6 +103,7 @@ class OAuth2AuthorizedClientResolver {
.switchIfEmpty(currentAuthentication());
Mono<String> defaultedRegistrationId = Mono.justOrEmpty(clientRegistrationId)
.switchIfEmpty(Mono.justOrEmpty(this.defaultClientRegistrationId))
.switchIfEmpty(clientRegistrationId(defaultedAuthentication))
.switchIfEmpty(Mono.error(() -> new IllegalArgumentException("The clientRegistrationId could not be resolved. Please provide one")));
@@ -300,6 +300,29 @@ public class ServerOAuth2AuthorizedClientExchangeFilterFunctionTests {
assertThat(getBody(request0)).isEmpty();
}
@Test
public void filterWhenDefaultClientRegistrationIdThenAuthorizedClientResolved() {
this.function.setDefaultClientRegistrationId(this.registration.getRegistrationId());
OAuth2RefreshToken refreshToken = new OAuth2RefreshToken("refresh-token", this.accessToken.getIssuedAt(), this.accessToken.getExpiresAt());
OAuth2AuthorizedClient authorizedClient = new OAuth2AuthorizedClient(this.registration,
"principalName", this.accessToken, refreshToken);
when(this.authorizedClientRepository.loadAuthorizedClient(any(), any(), any())).thenReturn(Mono.just(authorizedClient));
when(this.clientRegistrationRepository.findByRegistrationId(any())).thenReturn(Mono.just(this.registration));
ClientRequest request = ClientRequest.create(GET, URI.create("https://example.com"))
.build();
this.function.filter(request, this.exchange).block();
List<ClientRequest> requests = this.exchange.getRequests();
assertThat(requests).hasSize(1);
ClientRequest request0 = requests.get(0);
assertThat(request0.headers().getFirst(HttpHeaders.AUTHORIZATION)).isEqualTo("Bearer token-0");
assertThat(request0.url().toASCIIString()).isEqualTo("https://example.com");
assertThat(request0.method()).isEqualTo(HttpMethod.GET);
assertThat(getBody(request0)).isEmpty();
}
@Test
public void filterWhenClientRegistrationIdFromAuthenticationThenAuthorizedClientResolved() {
this.function.setDefaultOAuth2AuthorizedClient(true);
@@ -296,6 +296,28 @@ public class ServletOAuth2AuthorizedClientExchangeFilterFunctionTests {
assertThat(authorizedClient.getRefreshToken()).isEqualTo(accessTokenResponse.getRefreshToken());
}
@Test
public void defaultRequestWhenDefaultClientRegistrationIdThenAuthorizedClient() {
this.registration = TestClientRegistrations.clientCredentials().build();
this.function = new ServletOAuth2AuthorizedClientExchangeFilterFunction(this.clientRegistrationRepository,
this.authorizedClientRepository);
this.function.setDefaultClientRegistrationId(this.registration.getRegistrationId());
this.function.setClientCredentialsTokenResponseClient(this.clientCredentialsTokenResponseClient);
when(this.clientRegistrationRepository.findByRegistrationId(any())).thenReturn(this.registration);
OAuth2AccessTokenResponse accessTokenResponse = TestOAuth2AccessTokenResponses
.accessTokenResponse().build();
when(this.clientCredentialsTokenResponseClient.getTokenResponse(any())).thenReturn(
accessTokenResponse);
Map<String, Object> attrs = getDefaultRequestAttributes();
OAuth2AuthorizedClient authorizedClient = getOAuth2AuthorizedClient(attrs);
assertThat(authorizedClient.getAccessToken()).isEqualTo(accessTokenResponse.getAccessToken());
assertThat(authorizedClient.getClientRegistration()).isEqualTo(this.registration);
assertThat(authorizedClient.getPrincipalName()).isEqualTo("anonymousUser");
assertThat(authorizedClient.getRefreshToken()).isEqualTo(accessTokenResponse.getRefreshToken());
}
@Test
public void defaultRequestWhenClientIdNotFoundThenIllegalArgumentException() {
this.registration = TestClientRegistrations.clientCredentials().build();