Support additional client authentication methods

Closes gh-9780
This commit is contained in:
Steve Riesenberg 2021-06-16 15:18:14 -05:00
parent 9daf058a6e
commit a332e2a728
No known key found for this signature in database
GPG Key ID: 5F311AB48A55D521
2 changed files with 75 additions and 29 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2020 the original author or authors. * Copyright 2002-2021 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -239,8 +239,7 @@ public final class ClientRegistrations {
() -> "The Issuer \"" + metadataIssuer + "\" provided in the configuration metadata did " () -> "The Issuer \"" + metadataIssuer + "\" provided in the configuration metadata did "
+ "not match the requested issuer \"" + issuer + "\""); + "not match the requested issuer \"" + issuer + "\"");
String name = URI.create(issuer).getHost(); String name = URI.create(issuer).getHost();
ClientAuthenticationMethod method = getClientAuthenticationMethod(issuer, ClientAuthenticationMethod method = getClientAuthenticationMethod(metadata.getTokenEndpointAuthMethods());
metadata.getTokenEndpointAuthMethods());
Map<String, Object> configurationMetadata = new LinkedHashMap<>(metadata.toJSONObject()); Map<String, Object> configurationMetadata = new LinkedHashMap<>(metadata.toJSONObject());
// @formatter:off // @formatter:off
return ClientRegistration.withRegistrationId(name) return ClientRegistration.withRegistrationId(name)
@ -256,7 +255,7 @@ public final class ClientRegistrations {
// @formatter:on // @formatter:on
} }
private static ClientAuthenticationMethod getClientAuthenticationMethod(String issuer, private static ClientAuthenticationMethod getClientAuthenticationMethod(
List<com.nimbusds.oauth2.sdk.auth.ClientAuthenticationMethod> metadataAuthMethods) { List<com.nimbusds.oauth2.sdk.auth.ClientAuthenticationMethod> metadataAuthMethods) {
if (metadataAuthMethods == null || metadataAuthMethods if (metadataAuthMethods == null || metadataAuthMethods
.contains(com.nimbusds.oauth2.sdk.auth.ClientAuthenticationMethod.CLIENT_SECRET_BASIC)) { .contains(com.nimbusds.oauth2.sdk.auth.ClientAuthenticationMethod.CLIENT_SECRET_BASIC)) {
@ -269,10 +268,7 @@ public final class ClientRegistrations {
if (metadataAuthMethods.contains(com.nimbusds.oauth2.sdk.auth.ClientAuthenticationMethod.NONE)) { if (metadataAuthMethods.contains(com.nimbusds.oauth2.sdk.auth.ClientAuthenticationMethod.NONE)) {
return ClientAuthenticationMethod.NONE; return ClientAuthenticationMethod.NONE;
} }
throw new IllegalArgumentException( return null;
"Only ClientAuthenticationMethod.CLIENT_SECRET_BASIC, ClientAuthenticationMethod.CLIENT_SECRET_POST and "
+ "ClientAuthenticationMethod.NONE are supported. The issuer \"" + issuer
+ "\" returned a configuration of " + metadataAuthMethods);
} }
private interface ThrowingFunction<S, T, E extends Throwable> { private interface ThrowingFunction<S, T, E extends Throwable> {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2020 the original author or authors. * Copyright 2002-2021 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -298,6 +298,24 @@ public class ClientRegistrationsTests {
.isEqualTo(ClientAuthenticationMethod.CLIENT_SECRET_BASIC); .isEqualTo(ClientAuthenticationMethod.CLIENT_SECRET_BASIC);
} }
// gh-9780
@Test
public void issuerWhenClientSecretBasicAuthMethodThenMethodIsBasic() throws Exception {
this.response.put("token_endpoint_auth_methods_supported", Arrays.asList("client_secret_basic"));
ClientRegistration registration = registration("").build();
assertThat(registration.getClientAuthenticationMethod())
.isEqualTo(ClientAuthenticationMethod.CLIENT_SECRET_BASIC);
}
// gh-9780
@Test
public void issuerWhenOAuth2ClientSecretBasicAuthMethodThenMethodIsBasic() throws Exception {
this.response.put("token_endpoint_auth_methods_supported", Arrays.asList("client_secret_basic"));
ClientRegistration registration = registrationOAuth2("", null).build();
assertThat(registration.getClientAuthenticationMethod())
.isEqualTo(ClientAuthenticationMethod.CLIENT_SECRET_BASIC);
}
@Test @Test
public void issuerWhenTokenEndpointAuthMethodsPostThenMethodIsPost() throws Exception { public void issuerWhenTokenEndpointAuthMethodsPostThenMethodIsPost() 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("client_secret_post"));
@ -314,6 +332,46 @@ public class ClientRegistrationsTests {
.isEqualTo(ClientAuthenticationMethod.CLIENT_SECRET_POST); .isEqualTo(ClientAuthenticationMethod.CLIENT_SECRET_POST);
} }
// gh-9780
@Test
public void issuerWhenClientSecretJwtAuthMethodThenMethodIsClientSecretBasic() throws Exception {
this.response.put("token_endpoint_auth_methods_supported", Arrays.asList("client_secret_jwt"));
ClientRegistration registration = registration("").build();
// The client_secret_basic auth method is still the default
assertThat(registration.getClientAuthenticationMethod())
.isEqualTo(ClientAuthenticationMethod.CLIENT_SECRET_BASIC);
}
// gh-9780
@Test
public void issuerWhenOAuth2ClientSecretJwtAuthMethodThenMethodIsClientSecretBasic() throws Exception {
this.response.put("token_endpoint_auth_methods_supported", Arrays.asList("client_secret_jwt"));
ClientRegistration registration = registrationOAuth2("", null).build();
// The client_secret_basic auth method is still the default
assertThat(registration.getClientAuthenticationMethod())
.isEqualTo(ClientAuthenticationMethod.CLIENT_SECRET_BASIC);
}
// gh-9780
@Test
public void issuerWhenPrivateKeyJwtAuthMethodThenMethodIsClientSecretBasic() throws Exception {
this.response.put("token_endpoint_auth_methods_supported", Arrays.asList("private_key_jwt"));
ClientRegistration registration = registration("").build();
// The client_secret_basic auth method is still the default
assertThat(registration.getClientAuthenticationMethod())
.isEqualTo(ClientAuthenticationMethod.CLIENT_SECRET_BASIC);
}
// gh-9780
@Test
public void issuerWhenOAuth2PrivateKeyJwtAuthMethodThenMethodIsClientSecretBasic() throws Exception {
this.response.put("token_endpoint_auth_methods_supported", Arrays.asList("private_key_jwt"));
ClientRegistration registration = registrationOAuth2("", null).build();
// The client_secret_basic auth method is still the default
assertThat(registration.getClientAuthenticationMethod())
.isEqualTo(ClientAuthenticationMethod.CLIENT_SECRET_BASIC);
}
@Test @Test
public void issuerWhenTokenEndpointAuthMethodsNoneThenMethodIsNone() throws Exception { public void issuerWhenTokenEndpointAuthMethodsNoneThenMethodIsNone() throws Exception {
this.response.put("token_endpoint_auth_methods_supported", Arrays.asList("none")); this.response.put("token_endpoint_auth_methods_supported", Arrays.asList("none"));
@ -328,32 +386,24 @@ public class ClientRegistrationsTests {
assertThat(registration.getClientAuthenticationMethod()).isEqualTo(ClientAuthenticationMethod.NONE); assertThat(registration.getClientAuthenticationMethod()).isEqualTo(ClientAuthenticationMethod.NONE);
} }
/** // gh-9780
* We currently only support client_secret_basic, so verify we have a meaningful error
* until we add support.
*/
@Test @Test
public void issuerWhenTokenEndpointAuthMethodsInvalidThenException() { public void issuerWhenTlsClientAuthMethodThenSuccess() throws Exception {
this.response.put("token_endpoint_auth_methods_supported", Arrays.asList("tls_client_auth")); this.response.put("token_endpoint_auth_methods_supported", Arrays.asList("tls_client_auth"));
// @formatter:off ClientRegistration registration = registration("").build();
assertThatIllegalArgumentException() // The client_secret_basic auth method is still the default
.isThrownBy(() -> registration("")) assertThat(registration.getClientAuthenticationMethod())
.withMessageContaining("Only ClientAuthenticationMethod.CLIENT_SECRET_BASIC, ClientAuthenticationMethod.CLIENT_SECRET_POST and " .isEqualTo(ClientAuthenticationMethod.CLIENT_SECRET_BASIC);
+ "ClientAuthenticationMethod.NONE are supported. The issuer \"" + this.issuer
+ "\" returned a configuration of [tls_client_auth]");
// @formatter:on
} }
// gh-9780
@Test @Test
public void issuerWhenOAuth2TokenEndpointAuthMethodsInvalidThenException() { public void issuerWhenOAuth2TlsClientAuthMethodThenSuccess() throws Exception {
this.response.put("token_endpoint_auth_methods_supported", Arrays.asList("tls_client_auth")); this.response.put("token_endpoint_auth_methods_supported", Arrays.asList("tls_client_auth"));
// @formatter:off ClientRegistration registration = registrationOAuth2("", null).build();
assertThatIllegalArgumentException() // The client_secret_basic auth method is still the default
.isThrownBy(() -> registrationOAuth2("", null)) assertThat(registration.getClientAuthenticationMethod())
.withMessageContaining("Only ClientAuthenticationMethod.CLIENT_SECRET_BASIC, ClientAuthenticationMethod.CLIENT_SECRET_POST and " .isEqualTo(ClientAuthenticationMethod.CLIENT_SECRET_BASIC);
+ "ClientAuthenticationMethod.NONE are supported. The issuer \"" + this.issuer
+ "\" returned a configuration of [tls_client_auth]");
// @formatter:on
} }
@Test @Test