diff --git a/config/src/main/java/org/springframework/security/config/oauth2/client/oidc/OidcConfigurationProvider.java b/config/src/main/java/org/springframework/security/config/oauth2/client/oidc/OidcConfigurationProvider.java index 92c2417fac..98e9793814 100644 --- a/config/src/main/java/org/springframework/security/config/oauth2/client/oidc/OidcConfigurationProvider.java +++ b/config/src/main/java/org/springframework/security/config/oauth2/client/oidc/OidcConfigurationProvider.java @@ -72,13 +72,9 @@ public final class OidcConfigurationProvider { String openidConfiguration = rest.getForObject(issuer + "/.well-known/openid-configuration", String.class); OIDCProviderMetadata metadata = parse(openidConfiguration); String name = URI.create(issuer).getHost(); - List metadataAuthMethods = metadata.getTokenEndpointAuthMethods(); - // if null, the default includes client_secret_basic - if (metadataAuthMethods != null && !metadataAuthMethods.contains(com.nimbusds.oauth2.sdk.auth.ClientAuthenticationMethod.CLIENT_SECRET_BASIC)) { - throw new IllegalArgumentException("Only ClientAuthenticationMethod.BASIC is supported. The issuer \"" + issuer + "\" returned a configuration of " + metadataAuthMethods); - } + ClientAuthenticationMethod method = getClientAuthenticationMethod(issuer, metadata.getTokenEndpointAuthMethods()); List grantTypes = metadata.getGrantTypes(); - // If null, the default includes authorization_code + // If null, the default includes authorization_code if (grantTypes != null && !grantTypes.contains(GrantType.AUTHORIZATION_CODE)) { throw new IllegalArgumentException("Only AuthorizationGrantType.AUTHORIZATION_CODE is supported. The issuer \"" + issuer + "\" returned a configuration of " + grantTypes); } @@ -87,7 +83,7 @@ public final class OidcConfigurationProvider { .userNameAttributeName(IdTokenClaimNames.SUB) .scope(scopes) .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE) - .clientAuthenticationMethod(ClientAuthenticationMethod.BASIC) + .clientAuthenticationMethod(method) .redirectUriTemplate("{baseUrl}/{action}/oauth2/code/{registrationId}") .authorizationUri(metadata.getAuthorizationEndpointURI().toASCIIString()) .jwkSetUri(metadata.getJWKSetURI().toASCIIString()) @@ -96,6 +92,18 @@ public final class OidcConfigurationProvider { .clientName(issuer); } + + private static ClientAuthenticationMethod getClientAuthenticationMethod(String issuer, List metadataAuthMethods) { + if (metadataAuthMethods == null || metadataAuthMethods.contains(com.nimbusds.oauth2.sdk.auth.ClientAuthenticationMethod.CLIENT_SECRET_BASIC)) { + // If null, the default includes client_secret_basic + return ClientAuthenticationMethod.BASIC; + } + if (metadataAuthMethods.contains(com.nimbusds.oauth2.sdk.auth.ClientAuthenticationMethod.CLIENT_SECRET_POST)) { + return ClientAuthenticationMethod.POST; + } + throw new IllegalArgumentException("Only ClientAuthenticationMethod.BASIC and ClientAuthenticationMethod.POST are supported. The issuer \"" + issuer + "\" returned a configuration of " + metadataAuthMethods); + } + private static List getScopes(OIDCProviderMetadata metadata) { Scope scope = metadata.getScopes(); if (scope == null) { diff --git a/config/src/test/java/org/springframework/security/config/oauth2/client/oidc/OidcConfigurationProviderTests.java b/config/src/test/java/org/springframework/security/config/oauth2/client/oidc/OidcConfigurationProviderTests.java index b2b1420efa..fc0fe965f3 100644 --- a/config/src/test/java/org/springframework/security/config/oauth2/client/oidc/OidcConfigurationProviderTests.java +++ b/config/src/test/java/org/springframework/security/config/oauth2/client/oidc/OidcConfigurationProviderTests.java @@ -25,7 +25,6 @@ import org.junit.Before; import org.junit.Test; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; -import org.springframework.security.config.oauth2.client.oidc.OidcConfigurationProvider; import org.springframework.security.oauth2.client.registration.ClientRegistration; import org.springframework.security.oauth2.core.AuthorizationGrantType; import org.springframework.security.oauth2.core.ClientAuthenticationMethod; @@ -181,17 +180,26 @@ public class OidcConfigurationProviderTests { assertThat(registration.getClientAuthenticationMethod()).isEqualTo(ClientAuthenticationMethod.BASIC); } + @Test + public void issuerWhenTokenEndpointAuthMethodsPostThenMethodIsPost() throws Exception { + this.response.put("token_endpoint_auth_methods_supported", Arrays.asList("client_secret_post")); + + ClientRegistration registration = registration(""); + + assertThat(registration.getClientAuthenticationMethod()).isEqualTo(ClientAuthenticationMethod.POST); + } + /** * We currently only support client_secret_basic, so verify we have a meaningful error until we add support. * @throws Exception */ @Test public void issuerWhenTokenEndpointAuthMethodsInvalidThenException() throws Exception { - this.response.put("token_endpoint_auth_methods_supported", Arrays.asList("client_secret_post")); + this.response.put("token_endpoint_auth_methods_supported", Arrays.asList("tls_client_auth")); assertThatThrownBy(() -> registration("")) .isInstanceOf(IllegalArgumentException.class) - .hasMessageContaining("Only ClientAuthenticationMethod.BASIC is supported. The issuer \"" + this.issuer + "\" returned a configuration of [client_secret_post]"); + .hasMessageContaining("Only ClientAuthenticationMethod.BASIC and ClientAuthenticationMethod.POST are supported. The issuer \"" + this.issuer + "\" returned a configuration of [tls_client_auth]"); } private ClientRegistration registration(String path) throws Exception {