diff --git a/oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/introspection/SpringReactiveOpaqueTokenIntrospector.java b/oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/introspection/SpringReactiveOpaqueTokenIntrospector.java index bdd3f8d634b..a1b809f2491 100644 --- a/oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/introspection/SpringReactiveOpaqueTokenIntrospector.java +++ b/oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/introspection/SpringReactiveOpaqueTokenIntrospector.java @@ -268,6 +268,7 @@ default List getScopes() { * Used to build {@link SpringReactiveOpaqueTokenIntrospector}. * * @author Ngoc Nhan + * @author Andrey Litvitski * @since 6.5 */ public static final class Builder { @@ -278,6 +279,8 @@ public static final class Builder { private String clientSecret; + private WebClient.Builder webClientBuilder; + private Builder(String introspectionUri) { this.introspectionUri = introspectionUri; } @@ -308,13 +311,31 @@ public Builder clientSecret(String clientSecret) { return this; } + /** + * The builder will use the provided {@link WebClient.Builder} to build the + * {@link WebClient} used for token introspection requests. If not provided, a + * default builder will be used. + * @param webClientBuilder The {@link WebClient.Builder} to customize the HTTP + * client + * @return the {@link SpringReactiveOpaqueTokenIntrospector.Builder} + * @since 6.5 + */ + public Builder webClientBuilder(WebClient.Builder webClientBuilder) { + Assert.notNull(webClientBuilder, "webClientBuilder cannot be null"); + this.webClientBuilder = webClientBuilder; + return this; + } + /** * Creates a {@code SpringReactiveOpaqueTokenIntrospector} * @return the {@link SpringReactiveOpaqueTokenIntrospector} * @since 6.5 */ public SpringReactiveOpaqueTokenIntrospector build() { - WebClient webClient = WebClient.builder() + if (this.webClientBuilder == null) { + this.webClientBuilder = WebClient.builder(); + } + WebClient webClient = this.webClientBuilder .defaultHeaders((h) -> h.setBasicAuth(this.clientId, this.clientSecret)) .build(); return new SpringReactiveOpaqueTokenIntrospector(this.introspectionUri, 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 8f05bd12207..93b0aee0e86 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 @@ -297,6 +297,7 @@ public void introspectWithEncodeClientCredentialsThenOk() throws Exception { .withIntrospectionUri(introspectUri) .clientId("client&1") .clientSecret("secret@$2") + .webClientBuilder(WebClient.builder()) .build(); OAuth2AuthenticatedPrincipal authority = introspectionClient.introspect("token").block(); // @formatter:off