diff --git a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/OAuth2TokenIntrospection.java b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/OAuth2TokenIntrospection.java index 660604e43..58f0629d7 100644 --- a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/OAuth2TokenIntrospection.java +++ b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/OAuth2TokenIntrospection.java @@ -305,7 +305,7 @@ private void validate() { "aud must be of type List"); } if (this.claims.containsKey(OAuth2TokenIntrospectionClaimNames.ISS)) { - validateURL(this.claims.get(OAuth2TokenIntrospectionClaimNames.ISS), "iss must be a valid URL"); + validateIssuer(this.claims.get(OAuth2TokenIntrospectionClaimNames.ISS), "iss must not be empty"); } } @@ -326,16 +326,10 @@ private void acceptClaimValues(String name, Consumer> valuesConsume valuesConsumer.accept(values); } - private static void validateURL(Object url, String errorMessage) { - if (URL.class.isAssignableFrom(url.getClass())) { - return; - } - - try { - new URI(url.toString()).toURL(); - } - catch (Exception ex) { - throw new IllegalArgumentException(errorMessage, ex); + private static void validateIssuer(Object url, String errorMessage) { + String str = url.toString(); + if (str.isBlank()) { + throw new IllegalArgumentException(errorMessage); } } diff --git a/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/OAuth2TokenIntrospectionTests.java b/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/OAuth2TokenIntrospectionTests.java new file mode 100644 index 000000000..ee6478e48 --- /dev/null +++ b/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/OAuth2TokenIntrospectionTests.java @@ -0,0 +1,73 @@ +package org.springframework.security.oauth2.server.authorization; + +import org.junit.jupiter.api.Test; +import org.springframework.security.oauth2.core.OAuth2TokenIntrospectionClaimNames; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatCode; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +public class OAuth2TokenIntrospectionTests { + + @Test + void buildWhenIssuerIsNonUriStringThenDoesNotThrow() { + String issuer = "client-id-123"; // plain string, not a URI + + assertThatCode(() -> { + OAuth2TokenIntrospection token = + OAuth2TokenIntrospection.builder(true) + .issuer(issuer) + .subject("user-123") + .build(); + + Object issClaim = token.getClaim(OAuth2TokenIntrospectionClaimNames.ISS); + assertThat(issClaim).isEqualTo(issuer); + + Object activeClaim = token.getClaim(OAuth2TokenIntrospectionClaimNames.ACTIVE); + assertThat(activeClaim).isEqualTo(true); + }).doesNotThrowAnyException(); + } + + @Test + void buildWhenIssuerIsValidUriThenAcceptsIssuer() { + String issuer = "https://issuer.example.com"; + + OAuth2TokenIntrospection token = + OAuth2TokenIntrospection.builder(true) + .issuer(issuer) + .subject("user-123") + .build(); + + Object issClaim = token.getClaim(OAuth2TokenIntrospectionClaimNames.ISS); + assertThat(issClaim).isEqualTo(issuer); + + Object activeClaim = token.getClaim(OAuth2TokenIntrospectionClaimNames.ACTIVE); + assertThat(activeClaim).isEqualTo(true); + } + + @Test + void buildWithMultipleScopes() { + OAuth2TokenIntrospection token = + OAuth2TokenIntrospection.builder(true) + .scope("read") + .scope("write") + .build(); + + List scopes = (List) token.getClaim(OAuth2TokenIntrospectionClaimNames.SCOPE); + assertThat(scopes).containsExactly("read", "write"); + } + + @Test + void buildWhenIssuerIsBlankThenThrowsException() { + String issuer = " "; // blank string + + assertThatThrownBy(() -> + OAuth2TokenIntrospection.builder(true) + .issuer(issuer) + .subject("user-123") + .build() + ).isInstanceOf(IllegalArgumentException.class); + } +}