OIDC Provider Configuration - ClientRegistrations

OIDC Provider Configuration is now being used to create more than just
ClientRegistration instances. Also, the endpoint is being addressed in
more contexts than just the client.

To that end, this refactors OidcConfigurationProvider in the config
project to ClientRegistrations in the oauth2-client project.

Fixes: gh-5647
This commit is contained in:
Josh Cummings 2018-08-14 13:13:19 -06:00
parent cbdc7ee4b3
commit a4bd0d3923
No known key found for this signature in database
GPG Key ID: 49EF60DD7FF83443
2 changed files with 24 additions and 23 deletions

View File

@ -14,32 +14,32 @@
* limitations under the License. * limitations under the License.
*/ */
package org.springframework.security.config.oauth2.client.oidc; package org.springframework.security.oauth2.client.registration;
import java.net.URI; import java.net.URI;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import org.springframework.security.oauth2.client.registration.ClientRegistration;
import org.springframework.security.oauth2.core.AuthorizationGrantType;
import org.springframework.security.oauth2.core.ClientAuthenticationMethod;
import org.springframework.security.oauth2.core.oidc.IdTokenClaimNames;
import org.springframework.security.oauth2.core.oidc.OidcScopes;
import org.springframework.web.client.RestTemplate;
import com.nimbusds.oauth2.sdk.GrantType; import com.nimbusds.oauth2.sdk.GrantType;
import com.nimbusds.oauth2.sdk.ParseException; import com.nimbusds.oauth2.sdk.ParseException;
import com.nimbusds.oauth2.sdk.Scope; import com.nimbusds.oauth2.sdk.Scope;
import com.nimbusds.openid.connect.sdk.op.OIDCProviderMetadata; import com.nimbusds.openid.connect.sdk.op.OIDCProviderMetadata;
import org.springframework.security.oauth2.core.AuthorizationGrantType;
import org.springframework.security.oauth2.core.ClientAuthenticationMethod;
import org.springframework.security.oauth2.core.oidc.IdTokenClaimNames;
import org.springframework.security.oauth2.core.oidc.OidcScopes;
import org.springframework.web.client.RestTemplate;
/** /**
* Allows creating a {@link ClientRegistration.Builder} from an * Allows creating a {@link ClientRegistration.Builder} from an
* <a href="https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfig">OpenID Provider Configuration</a>. * <a href="https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfig">OpenID Provider Configuration</a>.
* *
* @author Rob Winch * @author Rob Winch
* @author Josh Cummings
* @since 5.1 * @since 5.1
*/ */
public final class OidcConfigurationProvider { public class ClientRegistrations {
/** /**
* Creates a {@link ClientRegistration.Builder} using the provided * Creates a {@link ClientRegistration.Builder} using the provided
@ -59,7 +59,7 @@ public final class OidcConfigurationProvider {
* Example usage: * Example usage:
* </p> * </p>
* <pre> * <pre>
* ClientRegistration registration = OidcConfigurationProvider.issuer("https://example.com") * ClientRegistration registration = ClientRegistrations.fromOidcIssuerLocation("https://example.com")
* .clientId("client-id") * .clientId("client-id")
* .clientSecret("client-secret") * .clientSecret("client-secret")
* .build(); * .build();
@ -67,7 +67,7 @@ public final class OidcConfigurationProvider {
* @param issuer the <a href="http://openid.net/specs/openid-connect-core-1_0.html#IssuerIdentifier">Issuer</a> * @param issuer the <a href="http://openid.net/specs/openid-connect-core-1_0.html#IssuerIdentifier">Issuer</a>
* @return a {@link ClientRegistration.Builder} that was initialized by the OpenID Provider Configuration. * @return a {@link ClientRegistration.Builder} that was initialized by the OpenID Provider Configuration.
*/ */
public static ClientRegistration.Builder issuer(String issuer) { public static ClientRegistration.Builder fromOidcIssuerLocation(String issuer) {
String openidConfiguration = getOpenidConfiguration(issuer); String openidConfiguration = getOpenidConfiguration(issuer);
OIDCProviderMetadata metadata = parse(openidConfiguration); OIDCProviderMetadata metadata = parse(openidConfiguration);
String metadataIssuer = metadata.getIssuer().getValue(); String metadataIssuer = metadata.getIssuer().getValue();
@ -135,5 +135,6 @@ public final class OidcConfigurationProvider {
} }
} }
private OidcConfigurationProvider() {} private ClientRegistrations() {}
} }

View File

@ -14,7 +14,10 @@
* limitations under the License. * limitations under the License.
*/ */
package org.springframework.security.config.oauth2.client.oidc; package org.springframework.security.oauth2.client.registration;
import java.util.Arrays;
import java.util.Map;
import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
@ -23,22 +26,20 @@ import okhttp3.mockwebserver.MockWebServer;
import org.junit.After; import org.junit.After;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.security.oauth2.client.registration.ClientRegistration;
import org.springframework.security.oauth2.core.AuthorizationGrantType; import org.springframework.security.oauth2.core.AuthorizationGrantType;
import org.springframework.security.oauth2.core.ClientAuthenticationMethod; import org.springframework.security.oauth2.core.ClientAuthenticationMethod;
import java.util.Arrays; import static org.assertj.core.api.Assertions.assertThat;
import java.util.Map; import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.assertj.core.api.Assertions.*;
/** /**
* @author Rob Winch * @author Rob Winch
* @since 5.1 * @since 5.1
*/ */
public class OidcConfigurationProviderTests { public class ClientRegistrationsTest {
/** /**
* Contains all optional parameters that are found in ClientRegistration * Contains all optional parameters that are found in ClientRegistration
@ -162,7 +163,6 @@ public class OidcConfigurationProviderTests {
* We currently only support authorization_code, so verify we have a meaningful error until we add support. * We currently only support authorization_code, so verify we have a meaningful error until we add support.
* @throws Exception * @throws Exception
*/ */
@Test
public void issuerWhenGrantTypesSupportedInvalidThenException() throws Exception { public void issuerWhenGrantTypesSupportedInvalidThenException() throws Exception {
this.response.put("grant_types_supported", Arrays.asList("implicit")); this.response.put("grant_types_supported", Arrays.asList("implicit"));
@ -204,7 +204,7 @@ public class OidcConfigurationProviderTests {
@Test @Test
public void issuerWhenEmptyStringThenMeaningfulErrorMessage() { public void issuerWhenEmptyStringThenMeaningfulErrorMessage() {
assertThatThrownBy(() -> OidcConfigurationProvider.issuer("")) assertThatThrownBy(() -> ClientRegistrations.fromOidcIssuerLocation(""))
.hasMessageContaining("Unable to resolve the OpenID Configuration with the provided Issuer of \"\""); .hasMessageContaining("Unable to resolve the OpenID Configuration with the provided Issuer of \"\"");
} }
@ -216,7 +216,7 @@ public class OidcConfigurationProviderTests {
.setBody(body) .setBody(body)
.setHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE); .setHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
this.server.enqueue(mockResponse); this.server.enqueue(mockResponse);
assertThatThrownBy(() -> OidcConfigurationProvider.issuer(this.issuer)) assertThatThrownBy(() -> ClientRegistrations.fromOidcIssuerLocation(this.issuer))
.hasMessageContaining("The Issuer \"https://example.com\" provided in the OpenID Configuration did not match the requested issuer \"" + this.issuer + "\""); .hasMessageContaining("The Issuer \"https://example.com\" provided in the OpenID Configuration did not match the requested issuer \"" + this.issuer + "\"");
} }
@ -229,7 +229,7 @@ public class OidcConfigurationProviderTests {
.setHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE); .setHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
this.server.enqueue(mockResponse); this.server.enqueue(mockResponse);
return OidcConfigurationProvider.issuer(this.issuer) return ClientRegistrations.fromOidcIssuerLocation(this.issuer)
.clientId("client-id") .clientId("client-id")
.clientSecret("client-secret") .clientSecret("client-secret")
.build(); .build();