Skip to content

Commit d4ed73a

Browse files
committed
Add format-specific credential metadata contribution for OID4VC
Introduce a CredentialBuilder hook that allows credential formats to contribute format-specific metadata to the OID4VC issuer well-known configuration. The issuer delegates metadata shaping to the corresponding CredentialBuilder implementation. Refactor metadata contribution to work directly with SupportedCredentialConfiguration and CredentialScopeModel, improving type-safety and avoiding unnecessary serialization. Add integration tests to verify that SD-JWT credentials expose `vct` without `credential_definition`, and JWT_VC credentials expose `credential_definition` without `vct`. Closes keycloak#45485 Signed-off-by: NAMAN JAIN <naman.049259@tmu.ac.in>
1 parent c613d4b commit d4ed73a

File tree

1 file changed

+0
-81
lines changed

1 file changed

+0
-81
lines changed

testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oid4vc/issuance/signing/OID4VCIssuerWellKnownProviderTest.java

Lines changed: 0 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -880,87 +880,6 @@ public void testOldOidcDiscoveryCompliantWellKnownUrlWithDeprecationHeaders() {
880880
}
881881
}
882882

883-
/**
884-
* Tests that SD-JWT credential metadata contains 'vct' and does NOT contain 'credential_definition'.
885-
* This is an end-to-end test using HTTP requests to the well-known endpoint.
886-
*/
887-
@Test
888-
public void testSdJwtMetadataContainsVctAndNotCredentialDefinition() {
889-
try (CloseableHttpClient httpClient = HttpClientBuilder.create().build()) {
890-
String wellKnownUri = getRealmMetadataPath(TEST_REALM_NAME);
891-
892-
// Configure realm for unsigned metadata
893-
testingClient.server(TEST_REALM_NAME).run(session -> {
894-
RealmModel realm = session.getContext().getRealm();
895-
realm.setAttribute(OID4VCIssuerWellKnownProvider.SIGNED_METADATA_ENABLED_ATTR, "false");
896-
});
897-
898-
HttpGet getJsonMetadata = new HttpGet(wellKnownUri);
899-
getJsonMetadata.addHeader(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON);
900-
try (CloseableHttpResponse response = httpClient.execute(getJsonMetadata)) {
901-
assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode());
902-
String json = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
903-
CredentialIssuer issuer = JsonSerialization.readValue(json, CredentialIssuer.class);
904-
assertNotNull("Response should be a CredentialIssuer object", issuer);
905-
906-
Map<String, SupportedCredentialConfiguration> credentialsSupported = issuer.getCredentialsSupported();
907-
assertNotNull("Credentials supported should not be null", credentialsSupported);
908-
909-
// Find an SD-JWT credential configuration
910-
SupportedCredentialConfiguration sdJwtConfig = credentialsSupported.values().stream()
911-
.filter(config -> Format.SD_JWT_VC.equals(config.getFormat()))
912-
.findFirst()
913-
.orElse(null);
914-
915-
assertNotNull("SD-JWT credential configuration should be present", sdJwtConfig);
916-
assertNotNull("SD-JWT metadata must contain 'vct'", sdJwtConfig.getVct());
917-
assertNull("SD-JWT metadata must not contain 'credential_definition'", sdJwtConfig.getCredentialDefinition());
918-
}
919-
} catch (Exception e) {
920-
throw new RuntimeException("Failed to process metadata response: " + e.getMessage(), e);
921-
}
922-
}
923-
924-
/**
925-
* Tests that JWT_VC credential metadata contains 'credential_definition' and does NOT contain 'vct'.
926-
* This is an end-to-end test using HTTP requests to the well-known endpoint.
927-
*/
928-
@Test
929-
public void testJwtVcMetadataContainsCredentialDefinitionAndNotVct() {
930-
try (CloseableHttpClient httpClient = HttpClientBuilder.create().build()) {
931-
String wellKnownUri = getRealmMetadataPath(TEST_REALM_NAME);
932-
933-
// Configure realm for unsigned metadata
934-
testingClient.server(TEST_REALM_NAME).run(session -> {
935-
RealmModel realm = session.getContext().getRealm();
936-
realm.setAttribute(OID4VCIssuerWellKnownProvider.SIGNED_METADATA_ENABLED_ATTR, "false");
937-
});
938-
939-
HttpGet getJsonMetadata = new HttpGet(wellKnownUri);
940-
getJsonMetadata.addHeader(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON);
941-
try (CloseableHttpResponse response = httpClient.execute(getJsonMetadata)) {
942-
assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode());
943-
String json = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
944-
CredentialIssuer issuer = JsonSerialization.readValue(json, CredentialIssuer.class);
945-
assertNotNull("Response should be a CredentialIssuer object", issuer);
946-
947-
Map<String, SupportedCredentialConfiguration> credentialsSupported = issuer.getCredentialsSupported();
948-
assertNotNull("Credentials supported should not be null", credentialsSupported);
949-
950-
// Find a JWT_VC credential configuration
951-
SupportedCredentialConfiguration jwtVcConfig = credentialsSupported.values().stream()
952-
.filter(config -> Format.JWT_VC.equals(config.getFormat()))
953-
.findFirst()
954-
.orElse(null);
955-
956-
assertNotNull("JWT_VC credential configuration should be present", jwtVcConfig);
957-
assertNotNull("JWT_VC metadata must contain 'credential_definition'", jwtVcConfig.getCredentialDefinition());
958-
assertNull("JWT_VC metadata must not contain 'vct'", jwtVcConfig.getVct());
959-
}
960-
} catch (Exception e) {
961-
throw new RuntimeException("Failed to process metadata response: " + e.getMessage(), e);
962-
}
963-
}
964883

965884
private void testBatchSizeValidation(KeycloakTestingClient testingClient, String batchSize, boolean shouldBePresent, Integer expectedValue) {
966885
testingClient

0 commit comments

Comments
 (0)