From a742c0c3f244ccc5ce12e2c2450c5cccc4f54fa0 Mon Sep 17 00:00:00 2001 From: Rafael Dominguez <5624449+raphaelDL@users.noreply.github.com> Date: Fri, 16 Nov 2018 13:30:51 -0600 Subject: [PATCH] WebClientReactiveClientCredentialsTokenResponseClient.getTokenResponse expects 2xx http status code This ensures that token response is only extracted when ClientResponse has a successful status Fixes: gh-6089 --- ...veClientCredentialsTokenResponseClient.java | 13 ++++++++++++- ...entCredentialsTokenResponseClientTests.java | 18 ++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/endpoint/WebClientReactiveClientCredentialsTokenResponseClient.java b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/endpoint/WebClientReactiveClientCredentialsTokenResponseClient.java index 40bca7d36a..2a3ab05d77 100644 --- a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/endpoint/WebClientReactiveClientCredentialsTokenResponseClient.java +++ b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/endpoint/WebClientReactiveClientCredentialsTokenResponseClient.java @@ -25,6 +25,7 @@ import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; import org.springframework.web.reactive.function.BodyInserters; import org.springframework.web.reactive.function.client.WebClient; +import org.springframework.web.reactive.function.client.WebClientResponseException; import reactor.core.publisher.Mono; import java.util.Set; @@ -64,7 +65,17 @@ public class WebClientReactiveClientCredentialsTokenResponseClient implements Re .headers(headers(clientRegistration)) .body(body) .exchange() - .flatMap(response -> response.body(oauth2AccessTokenResponse())) + .flatMap(response ->{ + if (!response.statusCode().is2xxSuccessful()){ + // extract the contents of this into a method named oauth2AccessTokenResponse but has an argument for the response + throw WebClientResponseException.create(response.rawStatusCode(), + "Cannot get token, expected 2xx HTTP Status code", + null, + null, + null + ); + } + return response.body(oauth2AccessTokenResponse()); }) .map(response -> { if (response.getAccessToken().getScopes().isEmpty()) { response = OAuth2AccessTokenResponse.withResponse(response) diff --git a/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/endpoint/WebClientReactiveClientCredentialsTokenResponseClientTests.java b/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/endpoint/WebClientReactiveClientCredentialsTokenResponseClientTests.java index 510df757c5..6c227b336c 100644 --- a/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/endpoint/WebClientReactiveClientCredentialsTokenResponseClientTests.java +++ b/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/endpoint/WebClientReactiveClientCredentialsTokenResponseClientTests.java @@ -28,6 +28,7 @@ import org.springframework.security.oauth2.client.registration.ClientRegistratio import org.springframework.security.oauth2.client.registration.TestClientRegistrations; import org.springframework.security.oauth2.core.ClientAuthenticationMethod; import org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse; +import org.springframework.web.reactive.function.client.WebClientResponseException; import static org.assertj.core.api.Assertions.*; @@ -116,6 +117,23 @@ public class WebClientReactiveClientCredentialsTokenResponseClientTests { assertThat(response.getAccessToken().getScopes()).isEqualTo(registration.getScopes()); } + @Test(expected = WebClientResponseException.class) + // gh-6089 + public void getTokenResponseWhenInvalidResponse() throws WebClientResponseException { + ClientRegistration registration = this.clientRegistration.build(); + enqueueUnexpectedResponse(); + + OAuth2ClientCredentialsGrantRequest request = new OAuth2ClientCredentialsGrantRequest(registration); + + OAuth2AccessTokenResponse response = this.client.getTokenResponse(request).block(); + } + + private void enqueueUnexpectedResponse(){ + MockResponse response = new MockResponse() + .setHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) + .setResponseCode(301); + this.server.enqueue(response); + } private void enqueueJson(String body) { MockResponse response = new MockResponse()