From 2dbf3a2d181febebccf3f6268da19e85dd28244e Mon Sep 17 00:00:00 2001 From: Rob Winch <362503+rwinch@users.noreply.github.com> Date: Tue, 6 May 2025 11:41:34 -0500 Subject: [PATCH] WebClient.exchange->exchangeToMono Closes gh-17057 --- .../NimbusReactiveOpaqueTokenIntrospector.java | 10 ++++------ .../NimbusReactiveOpaqueTokenIntrospectorTests.java | 13 +++++++++++-- .../SpringReactiveOpaqueTokenIntrospectorTests.java | 2 +- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/introspection/NimbusReactiveOpaqueTokenIntrospector.java b/oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/introspection/NimbusReactiveOpaqueTokenIntrospector.java index b7debd105c..6593248360 100644 --- a/oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/introspection/NimbusReactiveOpaqueTokenIntrospector.java +++ b/oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/introspection/NimbusReactiveOpaqueTokenIntrospector.java @@ -98,9 +98,8 @@ public class NimbusReactiveOpaqueTokenIntrospector implements ReactiveOpaqueToke @Override public Mono introspect(String token) { // @formatter:off - return Mono.just(token) - .flatMap(this::makeRequest) - .flatMap(this::adaptToNimbusResponse) + return this.makeRequest(token) + .exchangeToMono(this::adaptToNimbusResponse) .map(this::parseNimbusResponse) .map(this::castToNimbusSuccess) .doOnNext((response) -> validate(token, response)) @@ -109,13 +108,12 @@ public class NimbusReactiveOpaqueTokenIntrospector implements ReactiveOpaqueToke // @formatter:on } - private Mono makeRequest(String token) { + private WebClient.RequestHeadersSpec makeRequest(String token) { // @formatter:off return this.webClient.post() .uri(this.introspectionUri) .header(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE) - .body(BodyInserters.fromFormData("token", token)) - .exchange(); + .body(BodyInserters.fromFormData("token", token)); // @formatter:on } diff --git a/oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/introspection/NimbusReactiveOpaqueTokenIntrospectorTests.java b/oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/introspection/NimbusReactiveOpaqueTokenIntrospectorTests.java index 68ff78a2ac..0b8dd246cd 100644 --- a/oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/introspection/NimbusReactiveOpaqueTokenIntrospectorTests.java +++ b/oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/introspection/NimbusReactiveOpaqueTokenIntrospectorTests.java @@ -23,6 +23,7 @@ import java.util.Base64; import java.util.HashMap; import java.util.Map; import java.util.Optional; +import java.util.function.Function; import net.minidev.json.JSONObject; import okhttp3.mockwebserver.Dispatcher; @@ -45,6 +46,7 @@ import org.springframework.web.reactive.function.client.WebClient; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; @@ -265,6 +267,7 @@ public class NimbusReactiveOpaqueTokenIntrospectorTests { } private WebClient mockResponse(String response, String mediaType) { + WebClient.ResponseSpec responseSpec = mock(WebClient.ResponseSpec.class); WebClient real = WebClient.builder().build(); WebClient.RequestBodyUriSpec spec = spy(real.post()); WebClient webClient = spy(WebClient.class); @@ -275,7 +278,13 @@ public class NimbusReactiveOpaqueTokenIntrospectorTests { ClientResponse.Headers headers = mock(ClientResponse.Headers.class); given(headers.contentType()).willReturn(Optional.ofNullable(mediaType).map(MediaType::parseMediaType)); given(clientResponse.headers()).willReturn(headers); - given(spec.exchange()).willReturn(Mono.just(clientResponse)); + given(responseSpec.bodyToMono(ClientResponse.class)).willReturn(Mono.just(clientResponse)); + given(spec.exchangeToMono(any())).willAnswer((invocation) -> { + Object[] args = invocation.getArguments(); + Function> fn = (Function>) args[0]; + return fn.apply(clientResponse); + }); + given(spec.retrieve()).willReturn(responseSpec); return webClient; } @@ -284,7 +293,7 @@ public class NimbusReactiveOpaqueTokenIntrospectorTests { WebClient.RequestBodyUriSpec spec = spy(real.post()); WebClient webClient = spy(WebClient.class); given(webClient.post()).willReturn(spec); - given(spec.exchange()).willThrow(ex); + given(spec.exchangeToMono(any())).willReturn(Mono.error(ex)); return webClient; } diff --git a/oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/introspection/SpringReactiveOpaqueTokenIntrospectorTests.java b/oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/introspection/SpringReactiveOpaqueTokenIntrospectorTests.java index da9d22df23..8f05bd1220 100644 --- a/oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/introspection/SpringReactiveOpaqueTokenIntrospectorTests.java +++ b/oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/introspection/SpringReactiveOpaqueTokenIntrospectorTests.java @@ -345,7 +345,7 @@ public class SpringReactiveOpaqueTokenIntrospectorTests { WebClient.RequestBodyUriSpec spec = spy(real.post()); WebClient webClient = spy(WebClient.class); given(webClient.post()).willReturn(spec); - given(spec.exchange()).willThrow(ex); + given(spec.exchangeToMono(any())).willThrow(ex); return webClient; }