diff --git a/oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/introspection/SpringOpaqueTokenIntrospector.java b/oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/introspection/SpringOpaqueTokenIntrospector.java index 2cd1a8fb34..e4b8e90256 100644 --- a/oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/introspection/SpringOpaqueTokenIntrospector.java +++ b/oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/introspection/SpringOpaqueTokenIntrospector.java @@ -361,6 +361,8 @@ public class SpringOpaqueTokenIntrospector implements OpaqueTokenIntrospector { * @since 6.5 */ public SpringOpaqueTokenIntrospector build() { + Assert.notNull(this.clientId, "clientId cannot be null"); + Assert.notNull(this.clientSecret, "clientSecret cannot be null"); RestTemplate restTemplate = new RestTemplate(); restTemplate.getInterceptors().add(new BasicAuthenticationInterceptor(this.clientId, this.clientSecret)); return new SpringOpaqueTokenIntrospector(this.introspectionUri, restTemplate); 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 bee71d57b7..c77f9b638b 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 @@ -314,6 +314,8 @@ public class SpringReactiveOpaqueTokenIntrospector implements ReactiveOpaqueToke * @since 6.5 */ public SpringReactiveOpaqueTokenIntrospector build() { + Assert.notNull(this.clientId, "clientId cannot be null"); + Assert.notNull(this.clientSecret, "clientSecret cannot be null"); WebClient webClient = WebClient.builder() .defaultHeaders((h) -> h.setBasicAuth(this.clientId, this.clientSecret)) .build(); diff --git a/oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/introspection/SpringOpaqueTokenIntrospectorTests.java b/oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/introspection/SpringOpaqueTokenIntrospectorTests.java index b75358ded7..8d00763caa 100644 --- a/oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/introspection/SpringOpaqueTokenIntrospectorTests.java +++ b/oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/introspection/SpringOpaqueTokenIntrospectorTests.java @@ -383,6 +383,13 @@ public class SpringOpaqueTokenIntrospectorTests { } } + // gh-19201 + @Test + public void builderWhenMissingClientCredentialsThenThrowsException() { + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> SpringOpaqueTokenIntrospector.withIntrospectionUri(INTROSPECTION_URL).build()); + } + private static ResponseEntity> response(String content) { HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); 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 d614a65275..95aa52cf1a 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 @@ -308,6 +308,13 @@ public class SpringReactiveOpaqueTokenIntrospectorTests { } } + // gh-19201 + @Test + public void builderWhenMissingClientCredentialsThenThrowsException() { + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> SpringReactiveOpaqueTokenIntrospector.withIntrospectionUri(INTROSPECTION_URL).build()); + } + private WebClient mockResponse(String response) { return mockResponse(toMap(response)); }