diff --git a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/registration/ClientRegistrations.java b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/registration/ClientRegistrations.java index d9ae09f329..54efef5107 100644 --- a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/registration/ClientRegistrations.java +++ b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/registration/ClientRegistrations.java @@ -17,7 +17,6 @@ package org.springframework.security.oauth2.client.registration; import java.net.URI; -import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -146,7 +145,7 @@ public final class ClientRegistrations { */ public static ClientRegistration.Builder fromOidcIssuerLocation(String issuer) { Assert.hasText(issuer, "issuer cannot be empty"); - return getBuilder(issuer, oidc(URI.create(issuer))); + return getBuilder(issuer, oidc(issuer)); } /** @@ -189,21 +188,17 @@ public final class ClientRegistrations { */ public static ClientRegistration.Builder fromIssuerLocation(String issuer) { Assert.hasText(issuer, "issuer cannot be empty"); - URI uri = URI.create(issuer); - return getBuilder(issuer, oidc(uri), oidcRfc8414(uri), oauth(uri)); + return getBuilder(issuer, oidc(issuer), oidcRfc8414(issuer), oauth(issuer)); } - private static Supplier oidc(URI issuer) { - // @formatter:off - URI uri = UriComponentsBuilder.fromUri(issuer) - .replacePath(issuer.getPath() + OIDC_METADATA_PATH) - .build(Collections.emptyMap()); + static Supplier oidc(String issuer) { + UriComponents uri = oidcUri(issuer); // @formatter:on return () -> { - RequestEntity request = RequestEntity.get(uri).build(); + RequestEntity request = RequestEntity.get(uri.toUriString()).build(); Map configuration = rest.exchange(request, typeReference).getBody(); OIDCProviderMetadata metadata = parse(configuration, OIDCProviderMetadata::parse); - ClientRegistration.Builder builder = withProviderConfiguration(metadata, issuer.toASCIIString()) + ClientRegistration.Builder builder = withProviderConfiguration(metadata, issuer) .jwkSetUri(metadata.getJWKSetURI().toASCIIString()); if (metadata.getUserInfoEndpointURI() != null) { builder.userInfoUri(metadata.getUserInfoEndpointURI().toASCIIString()); @@ -212,35 +207,48 @@ public final class ClientRegistrations { }; } - private static Supplier oidcRfc8414(String issuer) { - URI uri = oidcRfc8414Uri(issuer); + static UriComponents oidcUri(String issuer) { + UriComponents uri = UriComponentsBuilder.fromUriString(issuer).build(); + // @formatter:off + return UriComponentsBuilder.newInstance().uriComponents(uri) + .replacePath(uri.getPath() + OIDC_METADATA_PATH) + .build(); + } + + static Supplier oidcRfc8414(String issuer) { + UriComponents uri = oidcRfc8414Uri(issuer); + // @formatter:on return getRfc8414Builder(issuer, uri); } - static URI oidcRfc8414Uri(String issuer) { + static UriComponents oidcRfc8414Uri(String issuer) { UriComponents uri = UriComponentsBuilder.fromUriString(issuer).build(); // @formatter:off return UriComponentsBuilder.newInstance().uriComponents(uri) .replacePath(OIDC_METADATA_PATH + uri.getPath()) - .build(Collections.emptyMap()); - // @formatter:on + .build(); } - private static Supplier oauth(URI issuer) { - // @formatter:off - URI uri = UriComponentsBuilder.fromUri(issuer) - .replacePath(OAUTH_METADATA_PATH + issuer.getPath()) - .build(Collections.emptyMap()); - // @formatter:on + static Supplier oauth(String issuer) { + UriComponents uri = oauthUri(issuer); return getRfc8414Builder(issuer, uri); } - private static Supplier getRfc8414Builder(URI issuer, URI uri) { + static UriComponents oauthUri(String issuer) { + UriComponents uri = UriComponentsBuilder.fromUriString(issuer).build(); + // @formatter:off + return UriComponentsBuilder.newInstance().uriComponents(uri) + .replacePath(OAUTH_METADATA_PATH + uri.getPath()) + .build(); + // @formatter:on + } + + private static Supplier getRfc8414Builder(String issuer, UriComponents uri) { return () -> { - RequestEntity request = RequestEntity.get(uri).build(); + RequestEntity request = RequestEntity.get(uri.toUriString()).build(); Map configuration = rest.exchange(request, typeReference).getBody(); AuthorizationServerMetadata metadata = parse(configuration, AuthorizationServerMetadata::parse); - ClientRegistration.Builder builder = withProviderConfiguration(metadata, issuer.toASCIIString()); + ClientRegistration.Builder builder = withProviderConfiguration(metadata, issuer); URI jwkSetUri = metadata.getJWKSetURI(); if (jwkSetUri != null) { builder.jwkSetUri(jwkSetUri.toASCIIString()); diff --git a/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/registration/ClientRegistrationsTests.java b/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/registration/ClientRegistrationsTests.java index 59c0fb0528..f66fe39454 100644 --- a/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/registration/ClientRegistrationsTests.java +++ b/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/registration/ClientRegistrationsTests.java @@ -34,6 +34,7 @@ import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.security.oauth2.core.AuthorizationGrantType; import org.springframework.security.oauth2.core.ClientAuthenticationMethod; +import org.springframework.web.util.UriComponents; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; @@ -569,6 +570,17 @@ public class ClientRegistrationsTests { .isEqualTo(ClientAuthenticationMethod.CLIENT_SECRET_BASIC); } + // gh-15852 + @Test + public void oidcWhenHostContainsUnderscoreThenRetains() { + UriComponents oidc = ClientRegistrations.oidcUri("https://elated_sutherland:8080/path"); + assertThat(oidc.getHost()).isEqualTo("elated_sutherland"); + UriComponents oauth = ClientRegistrations.oauthUri("https://elated_sutherland:8080/path"); + assertThat(oauth.getHost()).isEqualTo("elated_sutherland"); + UriComponents oidcRfc8414 = ClientRegistrations.oidcRfc8414Uri("https://elated_sutherland:8080/path"); + assertThat(oidcRfc8414.getHost()).isEqualTo("elated_sutherland"); + } + private ClientRegistration.Builder registration(String path) throws Exception { this.issuer = createIssuerFromServer(path); this.response.put("issuer", this.issuer);