diff --git a/core/pom.xml b/core/pom.xml index ad6d1a04b1..61068466a4 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -54,6 +54,10 @@ com.fasterxml.jackson.datatype jackson-datatype-jdk8 + + com.fasterxml.jackson.datatype + jackson-datatype-jsr310 + org.jboss.logging jboss-logging diff --git a/core/src/main/java/org/keycloak/util/JsonSerialization.java b/core/src/main/java/org/keycloak/util/JsonSerialization.java index e082ac54ba..e87275d7ae 100755 --- a/core/src/main/java/org/keycloak/util/JsonSerialization.java +++ b/core/src/main/java/org/keycloak/util/JsonSerialization.java @@ -25,6 +25,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.datatype.jdk8.Jdk8Module; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import java.io.IOException; import java.io.InputStream; @@ -43,6 +44,7 @@ public class JsonSerialization { static { mapper.registerModule(new Jdk8Module()); + mapper.registerModule(new JavaTimeModule()); mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); prettyMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); diff --git a/services/src/main/java/org/keycloak/protocol/oid4vc/issuance/OID4VCIssuerEndpoint.java b/services/src/main/java/org/keycloak/protocol/oid4vc/issuance/OID4VCIssuerEndpoint.java index 4162a086e2..4190f8f8f1 100644 --- a/services/src/main/java/org/keycloak/protocol/oid4vc/issuance/OID4VCIssuerEndpoint.java +++ b/services/src/main/java/org/keycloak/protocol/oid4vc/issuance/OID4VCIssuerEndpoint.java @@ -462,7 +462,7 @@ public class OID4VCIssuerEndpoint { // set the required claims VerifiableCredential vc = new VerifiableCredential() .setIssuer(URI.create(issuerDid)) - .setIssuanceDate(Date.from(Instant.ofEpochMilli(timeProvider.currentTimeMillis()))) + .setIssuanceDate(Instant.ofEpochMilli(timeProvider.currentTimeMillis())) .setType(List.of(vcType)); Map subjectClaims = new HashMap<>(); diff --git a/services/src/main/java/org/keycloak/protocol/oid4vc/issuance/signing/JwtSigningService.java b/services/src/main/java/org/keycloak/protocol/oid4vc/issuance/signing/JwtSigningService.java index fd076417ee..6424c0c595 100644 --- a/services/src/main/java/org/keycloak/protocol/oid4vc/issuance/signing/JwtSigningService.java +++ b/services/src/main/java/org/keycloak/protocol/oid4vc/issuance/signing/JwtSigningService.java @@ -28,6 +28,7 @@ import org.keycloak.protocol.oid4vc.model.VerifiableCredential; import org.keycloak.representations.JsonWebToken; import java.net.URI; +import java.time.Instant; import java.util.Optional; import java.util.UUID; @@ -74,7 +75,7 @@ public class JwtSigningService extends SigningService { // Get the issuance date from the credential. Since nbf is mandatory, we set it to the current time if not // provided long iat = Optional.ofNullable(verifiableCredential.getIssuanceDate()) - .map(issuanceDate -> issuanceDate.toInstant().getEpochSecond()) + .map(Instant::getEpochSecond) .orElse((long) timeProvider.currentTimeSeconds()); // set mandatory fields @@ -86,7 +87,7 @@ public class JwtSigningService extends SigningService { // expiry is optional Optional.ofNullable(verifiableCredential.getExpirationDate()) - .ifPresent(d -> jsonWebToken.exp(d.toInstant().getEpochSecond())); + .ifPresent(d -> jsonWebToken.exp(d.getEpochSecond())); // subject id should only be set if the credential subject has an id. Optional.ofNullable( @@ -110,4 +111,4 @@ public class JwtSigningService extends SigningService { .orElse(URI.create(String.format(ID_TEMPLATE, UUID.randomUUID()))) .toString(); } -} \ No newline at end of file +} diff --git a/services/src/main/java/org/keycloak/protocol/oid4vc/issuance/signing/LDSigningService.java b/services/src/main/java/org/keycloak/protocol/oid4vc/issuance/signing/LDSigningService.java index 1feb7a6c0b..548d03434a 100644 --- a/services/src/main/java/org/keycloak/protocol/oid4vc/issuance/signing/LDSigningService.java +++ b/services/src/main/java/org/keycloak/protocol/oid4vc/issuance/signing/LDSigningService.java @@ -18,7 +18,6 @@ package org.keycloak.protocol.oid4vc.issuance.signing; -import com.fasterxml.jackson.databind.ObjectMapper; import org.keycloak.common.util.Base64; import org.keycloak.crypto.KeyWrapper; import org.keycloak.crypto.SignatureProvider; @@ -48,7 +47,7 @@ public class LDSigningService extends SigningService { private final TimeProvider timeProvider; private final String keyId; - public LDSigningService(KeycloakSession keycloakSession, String keyId, String algorithmType, String ldpType, ObjectMapper objectMapper, TimeProvider timeProvider, Optional kid) { + public LDSigningService(KeycloakSession keycloakSession, String keyId, String algorithmType, String ldpType, TimeProvider timeProvider, Optional kid) { super(keycloakSession, keyId, algorithmType); this.timeProvider = timeProvider; this.keyId = kid.orElse(keyId); @@ -66,7 +65,7 @@ public class LDSigningService extends SigningService { linkedDataCryptographicSuite = switch (ldpType) { case Ed255192018Suite.PROOF_TYPE -> - new Ed255192018Suite(objectMapper, signatureProvider.signer(signingKey)); + new Ed255192018Suite(signatureProvider.signer(signingKey)); default -> throw new SigningServiceException(String.format("Proof Type %s is not supported.", ldpType)); }; } @@ -96,4 +95,4 @@ public class LDSigningService extends SigningService { throw new SigningServiceException("Was not able to encode the signature.", e); } } -} \ No newline at end of file +} diff --git a/services/src/main/java/org/keycloak/protocol/oid4vc/issuance/signing/LDSigningServiceProviderFactory.java b/services/src/main/java/org/keycloak/protocol/oid4vc/issuance/signing/LDSigningServiceProviderFactory.java index 3ca88c0312..f1de5e24db 100644 --- a/services/src/main/java/org/keycloak/protocol/oid4vc/issuance/signing/LDSigningServiceProviderFactory.java +++ b/services/src/main/java/org/keycloak/protocol/oid4vc/issuance/signing/LDSigningServiceProviderFactory.java @@ -17,7 +17,6 @@ package org.keycloak.protocol.oid4vc.issuance.signing; -import com.fasterxml.jackson.databind.ObjectMapper; import org.keycloak.component.ComponentModel; import org.keycloak.component.ComponentValidationException; import org.keycloak.models.KeycloakSession; @@ -39,15 +38,13 @@ public class LDSigningServiceProviderFactory implements VCSigningServiceProvider public static final String SUPPORTED_FORMAT = Format.LDP_VC; private static final String HELP_TEXT = "Issues Verifiable Credentials in the W3C Data Model, using Linked-Data Proofs. See https://www.w3.org/TR/vc-data-model/"; - private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); - @Override public VerifiableCredentialsSigningService create(KeycloakSession session, ComponentModel model) { String keyId = model.get(SigningProperties.KEY_ID.getKey()); String proofType = model.get(SigningProperties.PROOF_TYPE.getKey()); String algorithmType = model.get(SigningProperties.ALGORITHM_TYPE.getKey()); Optional kid = Optional.ofNullable(model.get(SigningProperties.KID_HEADER.getKey())); - return new LDSigningService(session, keyId, algorithmType, proofType, OBJECT_MAPPER, new OffsetTimeProvider(), kid); + return new LDSigningService(session, keyId, algorithmType, proofType, new OffsetTimeProvider(), kid); } @Override @@ -58,10 +55,10 @@ public class LDSigningServiceProviderFactory implements VCSigningServiceProvider @Override public List getConfigProperties() { return VCSigningServiceProviderFactory.configurationBuilder() - .property(SigningProperties.ALGORITHM_TYPE.asConfigProperty()) - .property(SigningProperties.PROOF_TYPE.asConfigProperty()) - .property(SigningProperties.KID_HEADER.asConfigProperty()) - .build(); + .property(SigningProperties.ALGORITHM_TYPE.asConfigProperty()) + .property(SigningProperties.PROOF_TYPE.asConfigProperty()) + .property(SigningProperties.KID_HEADER.asConfigProperty()) + .build(); } @Override @@ -72,8 +69,8 @@ public class LDSigningServiceProviderFactory implements VCSigningServiceProvider @Override public void validateSpecificConfiguration(KeycloakSession session, RealmModel realm, ComponentModel model) throws ComponentValidationException { ConfigurationValidationHelper.check(model) - .checkRequired(SigningProperties.ALGORITHM_TYPE.asConfigProperty()) - .checkRequired(SigningProperties.PROOF_TYPE.asConfigProperty()); + .checkRequired(SigningProperties.ALGORITHM_TYPE.asConfigProperty()) + .checkRequired(SigningProperties.PROOF_TYPE.asConfigProperty()); } @Override diff --git a/services/src/main/java/org/keycloak/protocol/oid4vc/issuance/signing/SdJwtSigningService.java b/services/src/main/java/org/keycloak/protocol/oid4vc/issuance/signing/SdJwtSigningService.java index e461bc0338..761e70fb6f 100644 --- a/services/src/main/java/org/keycloak/protocol/oid4vc/issuance/signing/SdJwtSigningService.java +++ b/services/src/main/java/org/keycloak/protocol/oid4vc/issuance/signing/SdJwtSigningService.java @@ -32,6 +32,7 @@ import org.keycloak.sdjwt.DisclosureSpec; import org.keycloak.sdjwt.SdJwt; import org.keycloak.sdjwt.SdJwtUtils; +import java.time.Instant; import java.util.List; import java.util.Optional; import java.util.stream.IntStream; @@ -121,7 +122,7 @@ public class SdJwtSigningService extends SigningService { // Get the issuance date from the credential. Since nbf is mandatory, we set it to the current time if not // provided long iat = Optional.ofNullable(verifiableCredential.getIssuanceDate()) - .map(issuanceDate -> issuanceDate.toInstant().getEpochSecond()) + .map(Instant::getEpochSecond) .orElse((long) timeProvider.currentTimeSeconds()); rootNode.put(NOT_BEFORE_CLAIM, iat); if (verifiableCredential.getType() == null || verifiableCredential.getType().size() != 1) { @@ -141,4 +142,4 @@ public class SdJwtSigningService extends SigningService { return sdJwt.toSdJwtString(); } -} \ No newline at end of file +} diff --git a/services/src/main/java/org/keycloak/protocol/oid4vc/issuance/signing/vcdm/Ed255192018Suite.java b/services/src/main/java/org/keycloak/protocol/oid4vc/issuance/signing/vcdm/Ed255192018Suite.java index decce22fef..ad23535b4b 100644 --- a/services/src/main/java/org/keycloak/protocol/oid4vc/issuance/signing/vcdm/Ed255192018Suite.java +++ b/services/src/main/java/org/keycloak/protocol/oid4vc/issuance/signing/vcdm/Ed255192018Suite.java @@ -31,13 +31,13 @@ import com.apicatalog.rdf.io.RdfWriter; import com.apicatalog.rdf.io.error.RdfWriterException; import com.apicatalog.rdf.io.error.UnsupportedContentException; import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; import io.setl.rdf.normalization.RdfNormalize; import jakarta.json.JsonObject; import jakarta.json.JsonValue; import org.keycloak.crypto.SignatureSignerContext; import org.keycloak.protocol.oid4vc.issuance.signing.SigningServiceException; import org.keycloak.protocol.oid4vc.model.VerifiableCredential; +import org.keycloak.util.JsonSerialization; import java.io.IOException; import java.io.StringReader; @@ -59,13 +59,11 @@ import java.util.Optional; */ public class Ed255192018Suite implements LinkedDataCryptographicSuite { - private final ObjectMapper objectMapper; private final SignatureSignerContext signerContext; public static final String PROOF_TYPE = "Ed25519Signature2018"; - public Ed255192018Suite(ObjectMapper objectMapper, SignatureSignerContext signerContext) { - this.objectMapper = objectMapper; + public Ed255192018Suite(SignatureSignerContext signerContext) { this.signerContext = signerContext; } @@ -79,7 +77,7 @@ public class Ed255192018Suite implements LinkedDataCryptographicSuite { private byte[] transform(VerifiableCredential verifiableCredential) { try { - String credentialString = objectMapper.writeValueAsString(verifiableCredential); + String credentialString = JsonSerialization.mapper.writeValueAsString(verifiableCredential); var credentialDocument = JsonDocument.of(new StringReader(credentialString)); @@ -134,4 +132,4 @@ public class Ed255192018Suite implements LinkedDataCryptographicSuite { public String getProofType() { return PROOF_TYPE; } -} \ No newline at end of file +} diff --git a/services/src/main/java/org/keycloak/protocol/oid4vc/model/VerifiableCredential.java b/services/src/main/java/org/keycloak/protocol/oid4vc/model/VerifiableCredential.java index 57ca589f7a..36c4ddf332 100644 --- a/services/src/main/java/org/keycloak/protocol/oid4vc/model/VerifiableCredential.java +++ b/services/src/main/java/org/keycloak/protocol/oid4vc/model/VerifiableCredential.java @@ -24,6 +24,7 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; import java.net.URI; +import java.time.Instant; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; @@ -50,9 +51,9 @@ public class VerifiableCredential { private List context = new ArrayList<>(List.of(VC_CONTEXT_V1)); private List type = new ArrayList<>(); private URI issuer; - private Date issuanceDate; + private Instant issuanceDate; private URI id; - private Date expirationDate; + private Instant expirationDate; private CredentialSubject credentialSubject = new CredentialSubject(); @JsonIgnore private Map additionalProperties = new HashMap<>(); @@ -95,11 +96,11 @@ public class VerifiableCredential { return this; } - public Date getIssuanceDate() { + public Instant getIssuanceDate() { return issuanceDate; } - public VerifiableCredential setIssuanceDate(Date issuanceDate) { + public VerifiableCredential setIssuanceDate(Instant issuanceDate) { this.issuanceDate = issuanceDate; return this; } @@ -113,11 +114,11 @@ public class VerifiableCredential { return this; } - public Date getExpirationDate() { + public Instant getExpirationDate() { return expirationDate; } - public VerifiableCredential setExpirationDate(Date expirationDate) { + public VerifiableCredential setExpirationDate(Instant expirationDate) { this.expirationDate = expirationDate; return this; } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oid4vc/issuance/signing/JwtSigningServiceTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oid4vc/issuance/signing/JwtSigningServiceTest.java index efa6dce176..e20f57f78e 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oid4vc/issuance/signing/JwtSigningServiceTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oid4vc/issuance/signing/JwtSigningServiceTest.java @@ -17,7 +17,6 @@ package org.keycloak.testsuite.oid4vc.issuance.signing; -import com.fasterxml.jackson.databind.ObjectMapper; import org.jboss.logging.Logger; import org.junit.Before; import org.junit.Test; @@ -38,10 +37,10 @@ import org.keycloak.protocol.oid4vc.model.VerifiableCredential; import org.keycloak.representations.JsonWebToken; import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.testsuite.runonserver.RunOnServerException; +import org.keycloak.util.JsonSerialization; import java.security.PublicKey; import java.time.Instant; -import java.util.Date; import java.util.List; import java.util.Map; import java.util.Optional; @@ -126,7 +125,7 @@ public class JwtSigningServiceTest extends OID4VCTest { Map.of("id", String.format("uri:uuid:%s", UUID.randomUUID()), "test", "test", "arrayClaim", List.of("a", "b", "c"), - "issuanceDate", Date.from(Instant.ofEpochSecond(10))))); + "issuanceDate", Instant.ofEpochSecond(10)))); } @Test @@ -184,19 +183,19 @@ public class JwtSigningServiceTest extends OID4VCTest { try { JsonWebToken theToken = verifier.getToken(); - assertEquals("JWT claim in JWT encoded VC or VP MUST be used to set the value of the “expirationDate” of the VC", TEST_EXPIRATION_DATE.toInstant().getEpochSecond(), theToken.getExp().longValue()); + assertEquals("JWT claim in JWT encoded VC or VP MUST be used to set the value of the “expirationDate” of the VC", TEST_EXPIRATION_DATE.getEpochSecond(), theToken.getExp().longValue()); if (claims.containsKey("issuanceDate")) { - assertEquals("VC Data Model v1.1 specifies that “issuanceDate” property MUST be represented as an nbf JWT claim, and not iat JWT claim.", ((Date) claims.get("issuanceDate")).toInstant().getEpochSecond(), theToken.getNbf().longValue()); + assertEquals("VC Data Model v1.1 specifies that “issuanceDate” property MUST be represented as an nbf JWT claim, and not iat JWT claim.", ((Instant) claims.get("issuanceDate")).getEpochSecond(), theToken.getNbf().longValue()); } else { // if not specific date is set, check against "currentTime" - assertEquals("VC Data Model v1.1 specifies that “issuanceDate” property MUST be represented as an nbf JWT claim, and not iat JWT claim.", TEST_ISSUANCE_DATE.toInstant().getEpochSecond(), theToken.getNbf().longValue()); + assertEquals("VC Data Model v1.1 specifies that “issuanceDate” property MUST be represented as an nbf JWT claim, and not iat JWT claim.", TEST_ISSUANCE_DATE.getEpochSecond(), theToken.getNbf().longValue()); } assertEquals("The issuer should be set in the token.", TEST_DID.toString(), theToken.getIssuer()); assertEquals("The credential ID should be set as the token ID.", testCredential.getId().toString(), theToken.getId()); Optional.ofNullable(testCredential.getCredentialSubject().getClaims().get("id")).ifPresent(id -> assertEquals("If the credentials subject id is set, it should be set as the token subject.", id.toString(), theToken.getSubject())); assertNotNull("The credentials should be included at the vc-claim.", theToken.getOtherClaims().get("vc")); - VerifiableCredential credential = new ObjectMapper().convertValue(theToken.getOtherClaims().get("vc"), VerifiableCredential.class); + VerifiableCredential credential = JsonSerialization.mapper.convertValue(theToken.getOtherClaims().get("vc"), VerifiableCredential.class); assertEquals("The types should be included", TEST_TYPES, credential.getType()); assertEquals("The issuer should be included", TEST_DID, credential.getIssuer()); assertEquals("The expiration date should be included", TEST_EXPIRATION_DATE, credential.getExpirationDate()); @@ -213,7 +212,7 @@ public class JwtSigningServiceTest extends OID4VCTest { } } - + @Override public void configureTestRealm(RealmRepresentation testRealm) { if (testRealm.getComponents() != null) { @@ -223,4 +222,4 @@ public class JwtSigningServiceTest extends OID4VCTest { Map.of("org.keycloak.keys.KeyProvider", List.of(getRsaKeyProvider(rsaKey))))); } } -} \ No newline at end of file +} diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oid4vc/issuance/signing/LDSigningServiceTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oid4vc/issuance/signing/LDSigningServiceTest.java index cb2e8d2fbd..57d3850d8f 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oid4vc/issuance/signing/LDSigningServiceTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oid4vc/issuance/signing/LDSigningServiceTest.java @@ -17,7 +17,6 @@ package org.keycloak.testsuite.oid4vc.issuance.signing; -import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.Before; import org.junit.Test; import org.keycloak.common.crypto.CryptoIntegration; @@ -33,7 +32,6 @@ import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.testsuite.runonserver.RunOnServerException; import java.time.Instant; -import java.util.Date; import java.util.List; import java.util.Map; import java.util.Optional; @@ -61,7 +59,6 @@ public class LDSigningServiceTest extends OID4VCTest { getKeyFromSession(session).getKid(), "EdDSA", "UnsupportedSignatureType", - new ObjectMapper(), new StaticTimeProvider(1000), Optional.empty())); } catch (RunOnServerException ros) { @@ -81,7 +78,6 @@ public class LDSigningServiceTest extends OID4VCTest { "no-such-key", "EdDSA", "Ed25519Signature2018", - new ObjectMapper(), new StaticTimeProvider(1000), Optional.empty())); } catch (RunOnServerException ros) { @@ -113,7 +109,7 @@ public class LDSigningServiceTest extends OID4VCTest { Map.of("id", String.format("uri:uuid:%s", UUID.randomUUID()), "test", "test", "arrayClaim", List.of("a", "b", "c"), - "issuanceDate", Date.from(Instant.ofEpochSecond(10))), + "issuanceDate", Instant.ofEpochSecond(10)), Optional.empty())); } @@ -127,7 +123,7 @@ public class LDSigningServiceTest extends OID4VCTest { Map.of("id", String.format("uri:uuid:%s", UUID.randomUUID()), "test", "test", "arrayClaim", List.of("a", "b", "c"), - "issuanceDate", Date.from(Instant.ofEpochSecond(10))), + "issuanceDate", Instant.ofEpochSecond(10)), Optional.of("did:web:test.org#the-key-id"))); } @@ -150,7 +146,6 @@ public class LDSigningServiceTest extends OID4VCTest { keyWrapper.getKid(), "EdDSA", "Ed25519Signature2018", - new ObjectMapper(), new StaticTimeProvider(1000), kid); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oid4vc/issuance/signing/OID4VCIssuerEndpointTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oid4vc/issuance/signing/OID4VCIssuerEndpointTest.java index b4a086952e..a7a9d1e81e 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oid4vc/issuance/signing/OID4VCIssuerEndpointTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oid4vc/issuance/signing/OID4VCIssuerEndpointTest.java @@ -51,7 +51,6 @@ import org.keycloak.common.util.SecretGenerator; import org.keycloak.crypto.Algorithm; import org.keycloak.models.KeycloakSession; import org.keycloak.models.UserSessionModel; -import org.keycloak.protocol.oid4vc.OID4VCLoginProtocolFactory; import org.keycloak.protocol.oid4vc.issuance.OID4VCIssuerEndpoint; import org.keycloak.protocol.oid4vc.issuance.OID4VCIssuerWellKnownProviderFactory; import org.keycloak.protocol.oid4vc.issuance.TimeProvider; @@ -89,10 +88,8 @@ import java.nio.charset.StandardCharsets; import java.util.LinkedList; import java.util.List; import java.util.Map; -import java.util.Optional; import java.util.function.BiFunction; import java.util.function.Consumer; -import java.util.function.Function; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -355,7 +352,6 @@ public class OID4VCIssuerEndpointTest extends OID4VCTest { @Test public void testRequestCredential() { String token = getBearerToken(oauth); - ObjectMapper objectMapper = new ObjectMapper(); testingClient .server(TEST_REALM_NAME) .run((session -> { @@ -373,7 +369,9 @@ public class OID4VCIssuerEndpointTest extends OID4VCTest { assertNotNull("A valid credential string should have been responded", jsonWebToken); assertNotNull("The credentials should be included at the vc-claim.", jsonWebToken.getOtherClaims().get("vc")); - VerifiableCredential credential = objectMapper.convertValue(jsonWebToken.getOtherClaims().get("vc"), VerifiableCredential.class); + VerifiableCredential credential = // + JsonSerialization.mapper.convertValue(jsonWebToken.getOtherClaims().get( + "vc"), VerifiableCredential.class); assertNotNull("@context is a required VC property", credential.getContext()); assertEquals(1, credential.getContext().size()); assertEquals(VerifiableCredential.VC_CONTEXT_V1, credential.getContext().get(0)); @@ -613,7 +611,7 @@ public class OID4VCIssuerEndpointTest extends OID4VCTest { JsonWebToken jsonWebToken = TokenVerifier.create((String) credentialResponse.getCredential(), JsonWebToken.class).getToken(); assertEquals("did:web:test.org", jsonWebToken.getIssuer()); - VerifiableCredential credential = new ObjectMapper().convertValue(jsonWebToken.getOtherClaims().get("vc"), VerifiableCredential.class); + VerifiableCredential credential = JsonSerialization.mapper.convertValue(jsonWebToken.getOtherClaims().get("vc"), VerifiableCredential.class); assertEquals(TEST_TYPES, credential.getType()); assertEquals(TEST_DID, credential.getIssuer()); assertEquals("john@email.cz", credential.getCredentialSubject().getClaims().get("email")); @@ -704,7 +702,7 @@ public class OID4VCIssuerEndpointTest extends OID4VCTest { assertNotNull("The credential should have been responded.", credentialResponse.getCredential()); JsonWebToken jsonWebToken = TokenVerifier.create((String) credentialResponse.getCredential(), JsonWebToken.class).getToken(); assertEquals("did:web:test.org", jsonWebToken.getIssuer()); - VerifiableCredential credential = new ObjectMapper().convertValue(jsonWebToken.getOtherClaims().get("vc"), VerifiableCredential.class); + VerifiableCredential credential = JsonSerialization.mapper.convertValue(jsonWebToken.getOtherClaims().get("vc"), VerifiableCredential.class); assertEquals(List.of("VerifiableCredential"), credential.getType()); assertEquals(URI.create("did:web:test.org"), credential.getIssuer()); assertEquals("john@email.cz", credential.getCredentialSubject().getClaims().get("email")); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oid4vc/issuance/signing/OID4VCTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oid4vc/issuance/signing/OID4VCTest.java index 954dda47b4..a323e1c4ee 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oid4vc/issuance/signing/OID4VCTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oid4vc/issuance/signing/OID4VCTest.java @@ -52,7 +52,6 @@ import java.security.PublicKey; import java.security.Security; import java.security.cert.Certificate; import java.time.Instant; -import java.util.Date; import java.util.List; import java.util.Map; import java.util.UUID; @@ -67,8 +66,8 @@ public abstract class OID4VCTest extends AbstractTestRealmKeycloakTest { protected static final String CONTEXT_URL = "https://www.w3.org/2018/credentials/v1"; protected static final URI TEST_DID = URI.create("did:web:test.org"); protected static final List TEST_TYPES = List.of("VerifiableCredential"); - protected static final Date TEST_EXPIRATION_DATE = Date.from(Instant.ofEpochSecond(2000)); - protected static final Date TEST_ISSUANCE_DATE = Date.from(Instant.ofEpochSecond(1000)); + protected static final Instant TEST_EXPIRATION_DATE = Instant.ofEpochSecond(2000); + protected static final Instant TEST_ISSUANCE_DATE = Instant.ofEpochSecond(1000); protected static final KeyWrapper RSA_KEY = getRsaKey(); @@ -87,7 +86,7 @@ public abstract class OID4VCTest extends AbstractTestRealmKeycloakTest { testCredential.setIssuer(TEST_DID); testCredential.setExpirationDate(TEST_EXPIRATION_DATE); if (claims.containsKey("issuanceDate")) { - testCredential.setIssuanceDate((Date) claims.get("issuanceDate")); + testCredential.setIssuanceDate((Instant) claims.get("issuanceDate")); } testCredential.setCredentialSubject(getCredentialSubject(claims)); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oid4vc/issuance/signing/SdJwtSigningServiceTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oid4vc/issuance/signing/SdJwtSigningServiceTest.java index c1e7abed65..b4c889f1b5 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oid4vc/issuance/signing/SdJwtSigningServiceTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oid4vc/issuance/signing/SdJwtSigningServiceTest.java @@ -243,7 +243,7 @@ public class SdJwtSigningServiceTest extends OID4VCTest { assertEquals("The credential ID should be set as the token ID.", testCredential.getId().toString(), theToken.getId()); assertEquals("The type should be included", TEST_TYPES.get(0), theToken.getOtherClaims().get("vct")); - assertEquals("The nbf date should be included", TEST_ISSUANCE_DATE.toInstant().getEpochSecond(), theToken.getNbf().longValue()); + assertEquals("The nbf date should be included", TEST_ISSUANCE_DATE.getEpochSecond(), theToken.getNbf().longValue()); List sds = (List) theToken.getOtherClaims().get("_sd"); if (sds != null && !sds.isEmpty()){