[java-idp-plugin-vci] 01/03: Include issuer if part of definition
Codeberg
noreply at shibboleth.net
Tue Apr 28 11:21:54 UTC 2026
This is an automated email from the git hooks/post-receive script.
codeberg pushed a commit to branch dev/VCDM
in repository java-idp-plugin-vci.
View the commit online:
https://codeberg.org/Shibboleth/java-idp-plugin-vci/commit/7686645f35d890addb419af42945ea53b72329ac
commit 7686645f35d890addb419af42945ea53b72329ac
Author: Janne Lauros <janne.lauros at csc.fi>
AuthorDate: Tue Apr 28 14:18:55 2026 +0300
Include issuer if part of definition
---
.../openidvci/credential/CredentialDefinition.java | 25 +++++++++++++++----
.../credential/CredentialDefinitionTest.java | 3 ++-
.../credentials/CredentialDefinition.json | 3 ++-
...FormJsonLdSelectiveDisclosureJWTCredential.java | 29 +++++++++++++++++++++-
4 files changed, 52 insertions(+), 8 deletions(-)
diff --git a/openid-vci-api/src/main/java/org/geant/shibboleth/plugin/openidvci/credential/CredentialDefinition.java b/openid-vci-api/src/main/java/org/geant/shibboleth/plugin/openidvci/credential/CredentialDefinition.java
index 96f3c48..e965571 100644
--- a/openid-vci-api/src/main/java/org/geant/shibboleth/plugin/openidvci/credential/CredentialDefinition.java
+++ b/openid-vci-api/src/main/java/org/geant/shibboleth/plugin/openidvci/credential/CredentialDefinition.java
@@ -17,7 +17,6 @@
package org.geant.shibboleth.plugin.openidvci.credential;
import java.util.List;
-import java.util.Map;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@@ -29,7 +28,6 @@ import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
-import com.nimbusds.oauth2.sdk.ParseException;
/**
* Credential definition in {@link CredentialConfiguration} as defined in
@@ -59,6 +57,20 @@ public class CredentialDefinition {
@JsonProperty("type")
private final List<String> type;
+ /** Issuer in credential definition. */
+ @Nullable
+ @JsonProperty("issuer")
+ @JsonInclude(Include.NON_NULL)
+ private final String issuer;
+
+ /**
+ *
+ * @return
+ */
+ public String getIssuer() {
+ return issuer;
+ }
+
/**
* Constructor.
*
@@ -67,12 +79,14 @@ public class CredentialDefinition {
* @param type Type of credential definition
*/
private CredentialDefinition(@JsonProperty("@context") @Nonnull List<String> context,
- @JsonProperty("id") @Nullable String id, @JsonProperty("type") @Nonnull List<String> type) {
+ @JsonProperty("id") @Nullable String id, @JsonProperty("type") @Nonnull List<String> type,
+ @JsonProperty("issuer") @Nullable String issuer) {
assert context != null;
assert type != null;
this.context = context;
this.type = type;
this.id = id;
+ this.issuer = issuer;
}
/**
@@ -129,10 +143,11 @@ public class CredentialDefinition {
@JsonCreator
public static CredentialDefinition of(@JsonProperty("@context") @Nullable List<String> context,
- @JsonProperty("id") @Nullable String id, @JsonProperty("type") @Nullable List<String> type) {
+ @JsonProperty("id") @Nullable String id, @JsonProperty("type") @Nullable List<String> type,
+ @JsonProperty("issuer") @Nullable String issuer) {
if (context == null || type == null) {
return null;
}
- return new CredentialDefinition(context, id, type);
+ return new CredentialDefinition(context, id, type, issuer);
}
}
diff --git a/openid-vci-api/src/test/java/org/geant/shibboleth/plugin/openidvci/credential/CredentialDefinitionTest.java b/openid-vci-api/src/test/java/org/geant/shibboleth/plugin/openidvci/credential/CredentialDefinitionTest.java
index ce9f2b3..7acdc46 100644
--- a/openid-vci-api/src/test/java/org/geant/shibboleth/plugin/openidvci/credential/CredentialDefinitionTest.java
+++ b/openid-vci-api/src/test/java/org/geant/shibboleth/plugin/openidvci/credential/CredentialDefinitionTest.java
@@ -49,8 +49,9 @@ public class CredentialDefinitionTest {
Assert.assertEquals(credentialDefinition.getType().get(0), "VerifiableCredential");
Assert.assertEquals(credentialDefinition.getType().get(1), "UniversityDegreeCredential");
Assert.assertEquals(credentialDefinition.getId(), "http://university.example/credentials/3732");
+ Assert.assertEquals(credentialDefinition.getIssuer(), "did:jwk:eyJrdHkiOiJFQyIsImNydiI6IlAtMjU2IiwieCI6IlREaW5WM3R5b2VUNEVmVU1Bd25QZnlkbkdzay1qVnczQlFXNldGdnZjRk0iLCJ5IjoiMGplbkx3UG9IbzRfM21Ma2gyMXV5Y0hWTzM3d2hCUTZqd3pDLV9VUXBsdyIsInVzZSI6InNpZyIsImFsZyI6IkVTMjU2In0");
Assert.assertEquals(credentialDefinition.serialize(),
- "{\"@context\":[\"https://www.w3.org/2018/credentials/v1\",\"https://www.w3.org/2018/credentials/examples/v1\"],\"id\":\"http://university.example/credentials/3732\",\"type\":[\"VerifiableCredential\",\"UniversityDegreeCredential\"]}");
+ "{\"@context\":[\"https://www.w3.org/2018/credentials/v1\",\"https://www.w3.org/2018/credentials/examples/v1\"],\"id\":\"http://university.example/credentials/3732\",\"type\":[\"VerifiableCredential\",\"UniversityDegreeCredential\"],\"issuer\":\"did:jwk:eyJrdHkiOiJFQyIsImNydiI6IlAtMjU2IiwieCI6IlREaW5WM3R5b2VUNEVmVU1Bd25QZnlkbkdzay1qVnczQlFXNldGdnZjRk0iLCJ5IjoiMGplbkx3UG9IbzRfM21Ma2gyMXV5Y0hWTzM3d2hCUTZqd3pDLV9VUXBsdyIsInVzZSI6InNpZyIsImFsZyI6IkVTMjU2In0\"}");
}
diff --git a/openid-vci-api/src/test/resources/credentials/CredentialDefinition.json b/openid-vci-api/src/test/resources/credentials/CredentialDefinition.json
index 5b646e9..fb41c00 100644
--- a/openid-vci-api/src/test/resources/credentials/CredentialDefinition.json
+++ b/openid-vci-api/src/test/resources/credentials/CredentialDefinition.json
@@ -7,5 +7,6 @@
"type": [
"VerifiableCredential",
"UniversityDegreeCredential"
- ]
+ ],
+ "issuer": "did:jwk:eyJrdHkiOiJFQyIsImNydiI6IlAtMjU2IiwieCI6IlREaW5WM3R5b2VUNEVmVU1Bd25QZnlkbkdzay1qVnczQlFXNldGdnZjRk0iLCJ5IjoiMGplbkx3UG9IbzRfM21Ma2gyMXV5Y0hWTzM3d2hCUTZqd3pDLV9VUXBsdyIsInVzZSI6InNpZyIsImFsZyI6IkVTMjU2In0"
}
diff --git a/openid-vci-impl/src/main/java/org/geant/shibboleth/plugin/openidvci/profile/impl/FormJsonLdSelectiveDisclosureJWTCredential.java b/openid-vci-impl/src/main/java/org/geant/shibboleth/plugin/openidvci/profile/impl/FormJsonLdSelectiveDisclosureJWTCredential.java
index f911795..692b895 100644
--- a/openid-vci-impl/src/main/java/org/geant/shibboleth/plugin/openidvci/profile/impl/FormJsonLdSelectiveDisclosureJWTCredential.java
+++ b/openid-vci-impl/src/main/java/org/geant/shibboleth/plugin/openidvci/profile/impl/FormJsonLdSelectiveDisclosureJWTCredential.java
@@ -20,6 +20,7 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.function.Function;
import javax.annotation.Nonnull;
@@ -35,7 +36,9 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import net.shibboleth.idp.profile.AbstractProfileAction;
+import net.shibboleth.profile.context.navigate.IssuerLookupFunction;
import net.shibboleth.shared.annotation.constraint.NonnullBeforeExec;
+import net.shibboleth.shared.logic.Constraint;
import com.nimbusds.jwt.JWTClaimsSet;
import com.nimbusds.oauth2.sdk.ParseException;
@@ -68,6 +71,27 @@ public class FormJsonLdSelectiveDisclosureJWTCredential extends AbstractProfileA
@NonnullBeforeExec
private CredentialOfferRequestedCredential credential;
+ /** Strategy used to obtain the response issuer value. */
+ @Nonnull
+ private Function<ProfileRequestContext, String> issuerLookupStrategy;
+
+ /**
+ * Constructor.
+ */
+ public FormJsonLdSelectiveDisclosureJWTCredential() {
+ issuerLookupStrategy = (Function<ProfileRequestContext, String>) new IssuerLookupFunction();
+ }
+
+ /**
+ * Set the strategy used to locate the issuer value to use.
+ *
+ * @param strategy lookup strategy
+ */
+ public void setIssuerLookupStrategy(@Nonnull final Function<ProfileRequestContext, String> strategy) {
+ checkSetterPreconditions();
+ issuerLookupStrategy = Constraint.isNotNull(strategy, "IssuerLookupStrategy lookup strategy cannot be null");
+ }
+
@Override
protected boolean doPreExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
@@ -127,11 +151,14 @@ public class FormJsonLdSelectiveDisclosureJWTCredential extends AbstractProfileA
List<JWTClaimsSet> credentials = new ArrayList<>();
ctx.getCredentialShells().forEach(cred -> {
try {
+ String issuer = ctx.getCredentialConfiguration().getCredentialDefinition().getIssuer();
+ issuer = issuer == null ? issuerLookupStrategy.apply(profileRequestContext) : issuer;
credentials.add(new JWTClaimsSet.Builder(cred.toJWTClaimsSet())
.claim("@context", ctx.getCredentialConfiguration().getCredentialDefinition().getContext())
.claim("id", ctx.getCredentialConfiguration().getCredentialDefinition().getId())
.claim("type", ctx.getCredentialConfiguration().getCredentialDefinition().getType())
- .claim("credentialSubject", credentialSubject).claim("_sd_alg", "sha-256").build());
+ .claim("issuer", issuer).claim("credentialSubject", credentialSubject)
+ .claim("_sd_alg", "sha-256").build());
} catch (ParseException e) {
log.error("{} Parsing credential failed", getLogPrefix(), e);
ActionSupport.buildEvent(profileRequestContext, OpenIDVCIEventIds.INVALID_CREDENTIAL);
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list