From d710746db6e74f9da3518246f65c8a7185e012d8 Mon Sep 17 00:00:00 2001
From: Thomas Diesler
Date: Mon, 16 Mar 2026 14:30:47 +0100
Subject: [PATCH] [OID4VCI-HAIP] Pass oid4vci-1_0-issuer-metadata_test
Signed-off-by: Thomas Diesler
---
.../java/org/keycloak/common/Profile.java | 1 +
.../OIDCConfigurationRepresentation.java | 22 ++++
.../AuthenticationFlowError.java | 1 +
.../client/AbstractClientAuthenticator.java | 4 +
.../AttestationBasedClientAuthenticator.java | 111 ++++++++++++++++++
.../FederatedJWTClientAuthenticator.java | 5 +-
.../client/X509ClientAuthenticator.java | 4 -
.../protocol/oidc/OIDCLoginProtocol.java | 1 +
.../protocol/oidc/OIDCWellKnownProvider.java | 25 ++--
....authentication.ClientAuthenticatorFactory | 3 +-
.../tests/oid4vc/OID4VCIssuerTestBase.java | 7 ++
.../oid4vc/OIDCAuthorizationMetadataTest.java | 40 +++++++
.../OIDCAuthorizationMetadataABCATest.java | 40 +++++++
13 files changed, 248 insertions(+), 16 deletions(-)
create mode 100644 services/src/main/java/org/keycloak/authentication/authenticators/client/AttestationBasedClientAuthenticator.java
create mode 100644 tests/base/src/test/java/org/keycloak/tests/oid4vc/OIDCAuthorizationMetadataTest.java
create mode 100644 tests/base/src/test/java/org/keycloak/tests/oid4vc/abca/OIDCAuthorizationMetadataABCATest.java
diff --git a/common/src/main/java/org/keycloak/common/Profile.java b/common/src/main/java/org/keycloak/common/Profile.java
index d42a6145fcce..085b24925d32 100755
--- a/common/src/main/java/org/keycloak/common/Profile.java
+++ b/common/src/main/java/org/keycloak/common/Profile.java
@@ -98,6 +98,7 @@ public enum Feature {
STEP_UP_AUTHENTICATION_SAML("Step-up Authentication Saml", Type.PREVIEW, Feature.STEP_UP_AUTHENTICATION),
CLIENT_AUTH_FEDERATED("Authenticates client based on assertions issued by identity provider", Type.DEFAULT),
+ CLIENT_AUTH_ABCA("Attestation-Based Client Authentication", Type.EXPERIMENTAL),
SPIFFE("SPIFFE trust relationship provider", Type.PREVIEW),
diff --git a/core/src/main/java/org/keycloak/protocol/oidc/representations/OIDCConfigurationRepresentation.java b/core/src/main/java/org/keycloak/protocol/oidc/representations/OIDCConfigurationRepresentation.java
index 074b9a708026..8678abdcc508 100755
--- a/core/src/main/java/org/keycloak/protocol/oidc/representations/OIDCConfigurationRepresentation.java
+++ b/core/src/main/java/org/keycloak/protocol/oidc/representations/OIDCConfigurationRepresentation.java
@@ -115,6 +115,12 @@ public class OIDCConfigurationRepresentation {
@JsonProperty("token_endpoint_auth_signing_alg_values_supported")
private List tokenEndpointAuthSigningAlgValuesSupported;
+ @JsonProperty("client_attestation_signing_alg_values_supported")
+ private List clientAttestationSigningAlgValuesSupported;
+
+ @JsonProperty("client_attestation_pop_signing_alg_values_supported")
+ private List clientAttestationPopSigningAlgValuesSupported;
+
@JsonProperty("introspection_endpoint_auth_methods_supported")
private List introspectionEndpointAuthMethodsSupported;
@@ -410,6 +416,22 @@ public void setTokenEndpointAuthSigningAlgValuesSupported(List tokenEndp
this.tokenEndpointAuthSigningAlgValuesSupported = tokenEndpointAuthSigningAlgValuesSupported;
}
+ public List getClientAttestationSigningAlgValuesSupported() {
+ return clientAttestationSigningAlgValuesSupported;
+ }
+
+ public void setClientAttestationSigningAlgValuesSupported(List clientAttestationSigningAlgValuesSupported) {
+ this.clientAttestationSigningAlgValuesSupported = clientAttestationSigningAlgValuesSupported;
+ }
+
+ public List getClientAttestationPopSigningAlgValuesSupported() {
+ return clientAttestationPopSigningAlgValuesSupported;
+ }
+
+ public void setClientAttestationPopSigningAlgValuesSupported(List clientAttestationPopSigningAlgValuesSupported) {
+ this.clientAttestationPopSigningAlgValuesSupported = clientAttestationPopSigningAlgValuesSupported;
+ }
+
public List getIntrospectionEndpointAuthMethodsSupported() {
return introspectionEndpointAuthMethodsSupported;
}
diff --git a/server-spi-private/src/main/java/org/keycloak/authentication/AuthenticationFlowError.java b/server-spi-private/src/main/java/org/keycloak/authentication/AuthenticationFlowError.java
index 612b859e563a..869f3e7b1e58 100755
--- a/server-spi-private/src/main/java/org/keycloak/authentication/AuthenticationFlowError.java
+++ b/server-spi-private/src/main/java/org/keycloak/authentication/AuthenticationFlowError.java
@@ -47,5 +47,6 @@ public enum AuthenticationFlowError {
DISPLAY_NOT_SUPPORTED,
ACCESS_DENIED,
+ UNAUTHORIZED_CLIENT,
GENERIC_AUTHENTICATION_ERROR
}
diff --git a/services/src/main/java/org/keycloak/authentication/authenticators/client/AbstractClientAuthenticator.java b/services/src/main/java/org/keycloak/authentication/authenticators/client/AbstractClientAuthenticator.java
index 516df6e00eaf..238b80587880 100644
--- a/services/src/main/java/org/keycloak/authentication/authenticators/client/AbstractClientAuthenticator.java
+++ b/services/src/main/java/org/keycloak/authentication/authenticators/client/AbstractClientAuthenticator.java
@@ -23,11 +23,15 @@
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.KeycloakSessionFactory;
+import org.jboss.logging.Logger;
+
/**
* @author Marek Posolda
*/
public abstract class AbstractClientAuthenticator implements ClientAuthenticator, ClientAuthenticatorFactory {
+ protected final Logger logger = Logger.getLogger(getClass());
+
@Override
public ClientAuthenticator create() {
return this;
diff --git a/services/src/main/java/org/keycloak/authentication/authenticators/client/AttestationBasedClientAuthenticator.java b/services/src/main/java/org/keycloak/authentication/authenticators/client/AttestationBasedClientAuthenticator.java
new file mode 100644
index 000000000000..1738d4d8b082
--- /dev/null
+++ b/services/src/main/java/org/keycloak/authentication/authenticators/client/AttestationBasedClientAuthenticator.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2026 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.keycloak.authentication.authenticators.client;
+
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import jakarta.ws.rs.core.Response;
+
+import org.keycloak.Config;
+import org.keycloak.OAuthErrorException;
+import org.keycloak.authentication.AuthenticationFlowError;
+import org.keycloak.authentication.ClientAuthenticationFlowContext;
+import org.keycloak.common.Profile;
+import org.keycloak.models.AuthenticationExecutionModel;
+import org.keycloak.models.ClientModel;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.protocol.oidc.OIDCLoginProtocol;
+import org.keycloak.provider.EnvironmentDependentProviderFactory;
+import org.keycloak.provider.ProviderConfigProperty;
+
+import static jakarta.ws.rs.core.Response.Status.NOT_IMPLEMENTED;
+
+/**
+ * Attestation-Based Client Authentication based on Client Attestation JWT and PoP.
+ * See specs for more details.
+ *
+ * @author Thomas Diesler
+ */
+public class AttestationBasedClientAuthenticator extends AbstractClientAuthenticator implements EnvironmentDependentProviderFactory {
+
+ public static final String PROVIDER_ID = "client-attestation";
+
+ @Override
+ public String getId() {
+ return PROVIDER_ID;
+ }
+
+ @Override
+ public void authenticateClient(ClientAuthenticationFlowContext context) {
+ Response errorResponse = ClientAuthUtil.errorResponse(NOT_IMPLEMENTED.getStatusCode(), OAuthErrorException.UNAUTHORIZED_CLIENT,
+ "Attestation-Based Client Authentication not (yet) supported");
+ context.failure(AuthenticationFlowError.UNAUTHORIZED_CLIENT, errorResponse);
+ }
+
+ @Override
+ public String getDisplayType() {
+ return "Attestation-Based";
+ }
+
+ @Override
+ public boolean isConfigurable() {
+ return false;
+ }
+
+ @Override
+ public AuthenticationExecutionModel.Requirement[] getRequirementChoices() {
+ return REQUIREMENT_CHOICES;
+ }
+
+ @Override
+ public String getHelpText() {
+ return "Validates client based on a Client Attestation JWT and a PoP JWT which proves possession of the private key";
+ }
+
+ @Override
+ public List getConfigProperties() {
+ return List.of();
+ }
+
+ @Override
+ public List getConfigPropertiesPerClient() {
+ return List.of();
+ }
+
+ @Override
+ public Map getAdapterConfiguration(KeycloakSession session, ClientModel client) {
+ return Map.of();
+ }
+
+ @Override
+ public boolean isSupported(Config.Scope config) {
+ return Profile.isFeatureEnabled(Profile.Feature.CLIENT_AUTH_ABCA);
+ }
+
+ @Override
+ public Set getProtocolAuthenticatorMethods(String loginProtocol) {
+ if (loginProtocol.equals(OIDCLoginProtocol.LOGIN_PROTOCOL)) {
+ return Set.of(OIDCLoginProtocol.ATTEST_JWT_CLIENT_AUTH);
+ } else {
+ return Set.of();
+ }
+ }
+}
diff --git a/services/src/main/java/org/keycloak/authentication/authenticators/client/FederatedJWTClientAuthenticator.java b/services/src/main/java/org/keycloak/authentication/authenticators/client/FederatedJWTClientAuthenticator.java
index fad9283cfbf8..f2a94dae0bac 100644
--- a/services/src/main/java/org/keycloak/authentication/authenticators/client/FederatedJWTClientAuthenticator.java
+++ b/services/src/main/java/org/keycloak/authentication/authenticators/client/FederatedJWTClientAuthenticator.java
@@ -26,12 +26,9 @@
import org.keycloak.representations.JsonWebToken;
import org.keycloak.services.resources.IdentityBrokerService;
-import org.jboss.logging.Logger;
public class FederatedJWTClientAuthenticator extends AbstractClientAuthenticator implements EnvironmentDependentProviderFactory {
- private static final Logger LOGGER = Logger.getLogger(FederatedJWTClientAuthenticator.class);
-
public static final String PROVIDER_ID = "federated-jwt";
public static final String JWT_CREDENTIAL_ISSUER_KEY = "jwt.credential.issuer";
@@ -113,7 +110,7 @@ public void authenticateClient(ClientAuthenticationFlowContext context) {
context.failure(AuthenticationFlowError.INVALID_CLIENT_CREDENTIALS);
}
} catch (Exception e) {
- LOGGER.warn("Authentication failed", e);
+ logger.warn("Authentication failed", e);
context.failure(AuthenticationFlowError.INVALID_CLIENT_CREDENTIALS);
}
}
diff --git a/services/src/main/java/org/keycloak/authentication/authenticators/client/X509ClientAuthenticator.java b/services/src/main/java/org/keycloak/authentication/authenticators/client/X509ClientAuthenticator.java
index 661469429e8d..dc80b859bbba 100644
--- a/services/src/main/java/org/keycloak/authentication/authenticators/client/X509ClientAuthenticator.java
+++ b/services/src/main/java/org/keycloak/authentication/authenticators/client/X509ClientAuthenticator.java
@@ -28,8 +28,6 @@
import org.keycloak.provider.ProviderConfigProperty;
import org.keycloak.services.x509.X509ClientCertificateLookup;
-import org.jboss.logging.Logger;
-
public class X509ClientAuthenticator extends AbstractClientAuthenticator {
public static final String PROVIDER_ID = "client-x509";
@@ -56,8 +54,6 @@ public class X509ClientAuthenticator extends AbstractClientAuthenticator {
CUSTOM_OIDS_REVERSED.put("E", "1.2.840.113549.1.9.1"); // Another synonym for "EMAILADDRESS"
}
- private final static Logger logger = Logger.getLogger(X509ClientAuthenticator.class);
-
@Override
public void authenticateClient(ClientAuthenticationFlowContext context) {
diff --git a/services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocol.java b/services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocol.java
index 286296fcdfe6..37dc613d10e9 100755
--- a/services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocol.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocol.java
@@ -121,6 +121,7 @@ public class OIDCLoginProtocol implements LoginProtocol {
public static final String CLIENT_SECRET_JWT = "client_secret_jwt";
public static final String PRIVATE_KEY_JWT = "private_key_jwt";
public static final String TLS_CLIENT_AUTH = "tls_client_auth";
+ public static final String ATTEST_JWT_CLIENT_AUTH = "attest_jwt_client_auth";
/**
* This is just for legacy setups which expect an unencoded, non-RFC6749 compliant client secret send from Keycloak to an IdP.
diff --git a/services/src/main/java/org/keycloak/protocol/oidc/OIDCWellKnownProvider.java b/services/src/main/java/org/keycloak/protocol/oidc/OIDCWellKnownProvider.java
index ba196502d547..b9af5336f014 100755
--- a/services/src/main/java/org/keycloak/protocol/oidc/OIDCWellKnownProvider.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/OIDCWellKnownProvider.java
@@ -69,6 +69,8 @@
import org.keycloak.util.JsonSerialization;
import org.keycloak.wellknown.WellKnownProvider;
+import static org.keycloak.protocol.oidc.OIDCLoginProtocol.ATTEST_JWT_CLIENT_AUTH;
+
/**
* @author Stian Thorgersen
*/
@@ -153,10 +155,18 @@ public Object getConfig() {
config.setPromptValuesSupported(getPromptValuesSupported(realm));
- config.setTokenEndpointAuthMethodsSupported(getClientAuthMethodsSupported());
- config.setTokenEndpointAuthSigningAlgValuesSupported(getSupportedClientSigningAlgorithms(false));
- config.setIntrospectionEndpointAuthMethodsSupported(getClientAuthMethodsSupported());
- config.setIntrospectionEndpointAuthSigningAlgValuesSupported(getSupportedClientSigningAlgorithms(false));
+ List clientAuthMethodsSupported = getClientAuthMethodsSupported();
+ List supportedClientSigningAlgorithms = getSupportedClientSigningAlgorithms(false);
+
+ config.setTokenEndpointAuthMethodsSupported(clientAuthMethodsSupported);
+ config.setTokenEndpointAuthSigningAlgValuesSupported(supportedClientSigningAlgorithms);
+ config.setIntrospectionEndpointAuthMethodsSupported(clientAuthMethodsSupported);
+ config.setIntrospectionEndpointAuthSigningAlgValuesSupported(supportedClientSigningAlgorithms);
+
+ if (clientAuthMethodsSupported.contains(ATTEST_JWT_CLIENT_AUTH)) {
+ config.setClientAttestationSigningAlgValuesSupported(getSupportedSigningAlgorithms(false));
+ config.setClientAttestationPopSigningAlgValuesSupported(getSupportedSigningAlgorithms(false));
+ }
config.setAuthorizationSigningAlgValuesSupported(getSupportedSigningAlgorithms(false));
config.setAuthorizationEncryptionAlgValuesSupported(getSupportedEncryptionAlg(false));
@@ -199,8 +209,8 @@ public Object getConfig() {
// NOTE: Don't hardcode HTTPS checks here. JWKS URI is exposed just in the development/testing environment. For the production environment, the OIDCWellKnownProvider
// is not exposed over "http" at all.
config.setRevocationEndpoint(revocationEndpoint.toString());
- config.setRevocationEndpointAuthMethodsSupported(getClientAuthMethodsSupported());
- config.setRevocationEndpointAuthSigningAlgValuesSupported(getSupportedClientSigningAlgorithms(false));
+ config.setRevocationEndpointAuthMethodsSupported(clientAuthMethodsSupported);
+ config.setRevocationEndpointAuthSigningAlgValuesSupported(supportedClientSigningAlgorithms);
config.setBackchannelLogoutSupported(true);
config.setBackchannelLogoutSessionSupported(true);
@@ -249,11 +259,12 @@ private static List list(String... values) {
}
private List getClientAuthMethodsSupported() {
- return session.getKeycloakSessionFactory().getProviderFactoriesStream(ClientAuthenticator.class)
+ List clientAuthMethods = session.getKeycloakSessionFactory().getProviderFactoriesStream(ClientAuthenticator.class)
.map(ClientAuthenticatorFactory.class::cast)
.map(caf -> caf.getProtocolAuthenticatorMethods(OIDCLoginProtocol.LOGIN_PROTOCOL))
.flatMap(Collection::stream)
.collect(Collectors.toList());
+ return clientAuthMethods;
}
private List getSupportedAlgorithms(Class extends Provider> clazz, boolean includeNone) {
diff --git a/services/src/main/resources/META-INF/services/org.keycloak.authentication.ClientAuthenticatorFactory b/services/src/main/resources/META-INF/services/org.keycloak.authentication.ClientAuthenticatorFactory
index c0b35f485d72..192fd787b294 100644
--- a/services/src/main/resources/META-INF/services/org.keycloak.authentication.ClientAuthenticatorFactory
+++ b/services/src/main/resources/META-INF/services/org.keycloak.authentication.ClientAuthenticatorFactory
@@ -19,4 +19,5 @@ org.keycloak.authentication.authenticators.client.ClientIdAndSecretAuthenticator
org.keycloak.authentication.authenticators.client.JWTClientAuthenticator
org.keycloak.authentication.authenticators.client.JWTClientSecretAuthenticator
org.keycloak.authentication.authenticators.client.X509ClientAuthenticator
-org.keycloak.authentication.authenticators.client.FederatedJWTClientAuthenticator
\ No newline at end of file
+org.keycloak.authentication.authenticators.client.FederatedJWTClientAuthenticator
+org.keycloak.authentication.authenticators.client.AttestationBasedClientAuthenticator
diff --git a/tests/base/src/test/java/org/keycloak/tests/oid4vc/OID4VCIssuerTestBase.java b/tests/base/src/test/java/org/keycloak/tests/oid4vc/OID4VCIssuerTestBase.java
index 9846a42bf09b..833aca0b2ae3 100644
--- a/tests/base/src/test/java/org/keycloak/tests/oid4vc/OID4VCIssuerTestBase.java
+++ b/tests/base/src/test/java/org/keycloak/tests/oid4vc/OID4VCIssuerTestBase.java
@@ -404,6 +404,13 @@ public KeycloakServerConfigBuilder configure(KeycloakServerConfigBuilder config)
}
}
+ public static class VCTestServerWithABCAEnabled implements KeycloakServerConfig {
+ @Override
+ public KeycloakServerConfigBuilder configure(KeycloakServerConfigBuilder config) {
+ return config.features(Profile.Feature.OID4VC_VCI, Profile.Feature.CLIENT_AUTH_ABCA);
+ }
+ }
+
public static class VCTestRealmConfig implements RealmConfig {
public static final String TEST_REALM_NAME = "test";
diff --git a/tests/base/src/test/java/org/keycloak/tests/oid4vc/OIDCAuthorizationMetadataTest.java b/tests/base/src/test/java/org/keycloak/tests/oid4vc/OIDCAuthorizationMetadataTest.java
new file mode 100644
index 000000000000..ec1e669549ed
--- /dev/null
+++ b/tests/base/src/test/java/org/keycloak/tests/oid4vc/OIDCAuthorizationMetadataTest.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2024 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.keycloak.tests.oid4vc;
+
+import java.util.List;
+
+import org.keycloak.protocol.oidc.representations.OIDCConfigurationRepresentation;
+import org.keycloak.testframework.annotations.KeycloakIntegrationTest;
+
+import org.junit.jupiter.api.Test;
+
+import static org.keycloak.protocol.oidc.OIDCLoginProtocol.ATTEST_JWT_CLIENT_AUTH;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+
+
+@KeycloakIntegrationTest(config = OID4VCIssuerTestBase.VCTestServerConfig.class)
+public class OIDCAuthorizationMetadataTest extends OID4VCIssuerTestBase {
+
+ @Test
+ public void testTokenEndpointAuthMethods() {
+ OIDCConfigurationRepresentation oidcConfiguration = oauth.doWellKnownRequest();
+ List tokenAuthMethodsSupported = oidcConfiguration.getTokenEndpointAuthMethodsSupported();
+ assertFalse(tokenAuthMethodsSupported.contains(ATTEST_JWT_CLIENT_AUTH), "Should not contain: " + ATTEST_JWT_CLIENT_AUTH);
+ }
+}
diff --git a/tests/base/src/test/java/org/keycloak/tests/oid4vc/abca/OIDCAuthorizationMetadataABCATest.java b/tests/base/src/test/java/org/keycloak/tests/oid4vc/abca/OIDCAuthorizationMetadataABCATest.java
new file mode 100644
index 000000000000..99f6b745b484
--- /dev/null
+++ b/tests/base/src/test/java/org/keycloak/tests/oid4vc/abca/OIDCAuthorizationMetadataABCATest.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2024 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.keycloak.tests.oid4vc.abca;
+
+import java.util.List;
+
+import org.keycloak.protocol.oidc.representations.OIDCConfigurationRepresentation;
+import org.keycloak.testframework.annotations.KeycloakIntegrationTest;
+import org.keycloak.tests.oid4vc.OID4VCIssuerTestBase;
+
+import org.junit.jupiter.api.Test;
+
+import static org.keycloak.protocol.oidc.OIDCLoginProtocol.ATTEST_JWT_CLIENT_AUTH;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+@KeycloakIntegrationTest(config = OID4VCIssuerTestBase.VCTestServerWithABCAEnabled.class)
+public class OIDCAuthorizationMetadataABCATest extends OID4VCIssuerTestBase {
+
+ @Test
+ public void testTokenEndpointAuthMethods() {
+ OIDCConfigurationRepresentation oidcConfiguration = oauth.doWellKnownRequest();
+ List tokenAuthMethodsSupported = oidcConfiguration.getTokenEndpointAuthMethodsSupported();
+ assertTrue(tokenAuthMethodsSupported.contains(ATTEST_JWT_CLIENT_AUTH), "Should contain: " + ATTEST_JWT_CLIENT_AUTH);
+ }
+}