[java-idp-plugin-vci] 03/03: Validate requested credential can be formed prior forming response.

Codeberg noreply at shibboleth.net
Wed Dec 31 12:10:34 UTC 2025


This is an automated email from the git hooks/post-receive script.

codeberg pushed a commit to branch dev/W3CCred
in repository java-idp-plugin-vci.

View the commit online:
https://codeberg.org/Shibboleth/java-idp-plugin-vci/commit/b468bdf0914b7b9a12905d1d666bfdbefa74df47

commit b468bdf0914b7b9a12905d1d666bfdbefa74df47
Author: jlauros <janne.lauros at csc.fi>
AuthorDate: Wed Dec 31 14:10:17 2025 +0200

    Validate requested credential can be formed prior forming response.
---
 .../messaging/context/CredentialOfferContext.java  |   7 +-
 .../messaging/context/CredentialsContext.java      |  46 +++++++
 ...estCredentialConfigurationIdLookupFunction.java |  44 ++++++
 .../RequestCredentialIdentifierLookupFunction.java |  44 ++++++
 .../impl/AbstractCredentialValidationAction.java   |   6 +-
 .../FormOutboundCredentialsResponseMessage.java    |   9 +-
 .../profile/impl/ValidateCredentialOffering.java   |   2 +-
 .../profile/impl/ValidateRequestedCredential.java  | 150 ++++++++++++++++++---
 .../openid/vci/credentials/credentials-beans.xml   |   3 +-
 9 files changed, 276 insertions(+), 35 deletions(-)

diff --git a/openid-vci-impl/src/main/java/org/geant/shibboleth/plugin/openidvci/messaging/context/CredentialOfferContext.java b/openid-vci-impl/src/main/java/org/geant/shibboleth/plugin/openidvci/messaging/context/CredentialOfferContext.java
index 89ca169..71cf57d 100644
--- a/openid-vci-impl/src/main/java/org/geant/shibboleth/plugin/openidvci/messaging/context/CredentialOfferContext.java
+++ b/openid-vci-impl/src/main/java/org/geant/shibboleth/plugin/openidvci/messaging/context/CredentialOfferContext.java
@@ -21,6 +21,7 @@ import java.util.Map;
 
 import javax.annotation.Nullable;
 
+import org.geant.shibboleth.plugin.openidvci.credential.CredentialConfiguration;
 import org.geant.shibboleth.plugin.openidvci.credential.CredentialConfigurations;
 import org.geant.shibboleth.plugin.openidvci.messaging.impl.CredentialOfferRequestedCredential;
 import org.geant.shibboleth.plugin.openidvci.messaging.impl.CredentialOfferTxCode;
@@ -34,7 +35,7 @@ public class CredentialOfferContext extends BaseContext {
 
     /** Credential configuration supported. */
     @Nullable
-    private CredentialConfigurations credentialConfigurations;
+    private Map<String, CredentialConfiguration> credentialConfigurations;
 
     /** Credential offer request content in pre-auth flow. */
     @Nullable
@@ -60,7 +61,7 @@ public class CredentialOfferContext extends BaseContext {
      * @param credentialConfigurations credential configuration supported
      */
     @Nullable
-    public void setCredentialConfigurations(@Nullable CredentialConfigurations credentialConfigurations) {
+    public void setCredentialConfigurations(@Nullable Map<String, CredentialConfiguration> credentialConfigurations) {
         this.credentialConfigurations = credentialConfigurations;
     }
 
@@ -70,7 +71,7 @@ public class CredentialOfferContext extends BaseContext {
      * @return Credential configuration supported
      */
     @Nullable
-    public CredentialConfigurations getCredentialConfigurations() {
+    public Map<String, CredentialConfiguration> getCredentialConfigurations() {
         return credentialConfigurations;
     }
 
diff --git a/openid-vci-impl/src/main/java/org/geant/shibboleth/plugin/openidvci/messaging/context/CredentialsContext.java b/openid-vci-impl/src/main/java/org/geant/shibboleth/plugin/openidvci/messaging/context/CredentialsContext.java
index 28c914e..13ca331 100644
--- a/openid-vci-impl/src/main/java/org/geant/shibboleth/plugin/openidvci/messaging/context/CredentialsContext.java
+++ b/openid-vci-impl/src/main/java/org/geant/shibboleth/plugin/openidvci/messaging/context/CredentialsContext.java
@@ -20,6 +20,8 @@ import java.util.List;
 
 import javax.annotation.Nullable;
 
+import org.geant.shibboleth.plugin.openidvci.credential.CredentialConfiguration;
+import org.geant.shibboleth.plugin.openidvci.messaging.impl.CredentialOfferRequestedCredential;
 import org.opensaml.messaging.context.BaseContext;
 
 import com.nimbusds.jose.JWSObject;
@@ -30,6 +32,12 @@ import com.nimbusds.jose.JWSObject;
  */
 public class CredentialsContext extends BaseContext {
 
+    /** Credential content to be returned in response. */
+    private CredentialOfferRequestedCredential credential;
+
+    /** Credential configuration for the credential to be returned in response. */
+    private CredentialConfiguration configuration;
+
     /** Validated identifier for credential. */
     @Nullable
     private String credentialIdentifier;
@@ -57,6 +65,44 @@ public class CredentialsContext extends BaseContext {
         this.proofs = proofs;
     }
 
+    /**
+     * Get credential content to be returned in response.
+     * 
+     * @return Credential content to be returned in response
+     */
+    public CredentialOfferRequestedCredential getCredential() {
+        return credential;
+    }
+
+    /**
+     * Set credential content to be returned in response.
+     * 
+     * @param credential Credential content to be returned in response
+     */
+    public void setCredential(CredentialOfferRequestedCredential credential) {
+        this.credential = credential;
+    }
+
+    /**
+     * Get credential configuration for the credential to be returned in response.
+     * 
+     * @return Credential configuration for the credential to be returned in
+     *         response
+     */
+    public CredentialConfiguration getConfiguration() {
+        return configuration;
+    }
+
+    /**
+     * Set credential configuration for the credential to be returned in response.
+     * 
+     * @param configuration Credential configuration for the credential to be
+     *                      returned in response
+     */
+    public void setConfiguration(CredentialConfiguration configuration) {
+        this.configuration = configuration;
+    }
+
     /**
      * Set validated identifier for credential.
      * 
diff --git a/openid-vci-impl/src/main/java/org/geant/shibboleth/plugin/openidvci/messaging/context/navigate/RequestCredentialConfigurationIdLookupFunction.java b/openid-vci-impl/src/main/java/org/geant/shibboleth/plugin/openidvci/messaging/context/navigate/RequestCredentialConfigurationIdLookupFunction.java
new file mode 100644
index 0000000..bd052ec
--- /dev/null
+++ b/openid-vci-impl/src/main/java/org/geant/shibboleth/plugin/openidvci/messaging/context/navigate/RequestCredentialConfigurationIdLookupFunction.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2025, GÉANT
+ *
+ * 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.geant.shibboleth.plugin.openidvci.messaging.context.navigate;
+
+import org.geant.shibboleth.plugin.openidvci.messaging.impl.OpenIDVCICredentialsRequest;
+import org.opensaml.messaging.context.navigate.ContextDataLookupFunction;
+import org.opensaml.profile.context.ProfileRequestContext;
+
+/**
+ * For OpenID VCI Credentials endpoint.
+ * 
+ * A function that returns credential configuration id value of the credentials
+ * request via a lookup function. This default lookup locates credential
+ * configuration id from request if available. If information is not available,
+ * null is returned.
+ */
+public class RequestCredentialConfigurationIdLookupFunction
+        implements ContextDataLookupFunction<ProfileRequestContext, String> {
+
+    @Override
+    public String apply(ProfileRequestContext input) {
+        if (input == null || input.getInboundMessageContext() == null) {
+            return null;
+        }
+        if (input.getInboundMessageContext().getMessage() instanceof OpenIDVCICredentialsRequest credentialsRequest) {
+            return credentialsRequest.getCredentialConfigurationId();
+        }
+        return null;
+    }
+}
diff --git a/openid-vci-impl/src/main/java/org/geant/shibboleth/plugin/openidvci/messaging/context/navigate/RequestCredentialIdentifierLookupFunction.java b/openid-vci-impl/src/main/java/org/geant/shibboleth/plugin/openidvci/messaging/context/navigate/RequestCredentialIdentifierLookupFunction.java
new file mode 100644
index 0000000..b3a74a9
--- /dev/null
+++ b/openid-vci-impl/src/main/java/org/geant/shibboleth/plugin/openidvci/messaging/context/navigate/RequestCredentialIdentifierLookupFunction.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2025, GÉANT
+ *
+ * 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.geant.shibboleth.plugin.openidvci.messaging.context.navigate;
+
+import org.geant.shibboleth.plugin.openidvci.messaging.impl.OpenIDVCICredentialsRequest;
+import org.opensaml.messaging.context.navigate.ContextDataLookupFunction;
+import org.opensaml.profile.context.ProfileRequestContext;
+
+/**
+ * For OpenID VCI Credentials endpoint.
+ * 
+ * A function that returns credential identifier value of the credentials
+ * request via a lookup function. This default lookup locates credential
+ * identifier from request if available. If information is not available, null
+ * is returned.
+ */
+public class RequestCredentialIdentifierLookupFunction
+        implements ContextDataLookupFunction<ProfileRequestContext, String> {
+
+    @Override
+    public String apply(ProfileRequestContext input) {
+        if (input == null || input.getInboundMessageContext() == null) {
+            return null;
+        }
+        if (input.getInboundMessageContext().getMessage() instanceof OpenIDVCICredentialsRequest credentialsRequest) {
+            return credentialsRequest.getCredentialIdentifier();
+        }
+        return null;
+    }
+}
diff --git a/openid-vci-impl/src/main/java/org/geant/shibboleth/plugin/openidvci/profile/impl/AbstractCredentialValidationAction.java b/openid-vci-impl/src/main/java/org/geant/shibboleth/plugin/openidvci/profile/impl/AbstractCredentialValidationAction.java
index 1ed34d3..e01b26e 100644
--- a/openid-vci-impl/src/main/java/org/geant/shibboleth/plugin/openidvci/profile/impl/AbstractCredentialValidationAction.java
+++ b/openid-vci-impl/src/main/java/org/geant/shibboleth/plugin/openidvci/profile/impl/AbstractCredentialValidationAction.java
@@ -17,9 +17,11 @@
 package org.geant.shibboleth.plugin.openidvci.profile.impl;
 
 import java.io.IOException;
+import java.util.Map;
 
 import javax.annotation.Nonnull;
 
+import org.geant.shibboleth.plugin.openidvci.credential.CredentialConfiguration;
 import org.geant.shibboleth.plugin.openidvci.credential.CredentialConfigurations;
 import org.geant.shibboleth.plugin.openidvci.profile.OpenIDVCIEventIds;
 import org.opensaml.profile.action.ActionSupport;
@@ -71,8 +73,8 @@ abstract class AbstractCredentialValidationAction extends AbstractProfileAction
      * 
      * @return Supported credentials parsed from file
      */
-    public CredentialConfigurations getCredentialConfigurations() {
-        return credentialConfigurations;
+    public Map<String, CredentialConfiguration> getCredentialConfigurations() {
+        return credentialConfigurations.getCredentialConfigurations();
     }
 
     /** {@inheritDoc} */
diff --git a/openid-vci-impl/src/main/java/org/geant/shibboleth/plugin/openidvci/profile/impl/FormOutboundCredentialsResponseMessage.java b/openid-vci-impl/src/main/java/org/geant/shibboleth/plugin/openidvci/profile/impl/FormOutboundCredentialsResponseMessage.java
index 239e1e9..7642474 100644
--- a/openid-vci-impl/src/main/java/org/geant/shibboleth/plugin/openidvci/profile/impl/FormOutboundCredentialsResponseMessage.java
+++ b/openid-vci-impl/src/main/java/org/geant/shibboleth/plugin/openidvci/profile/impl/FormOutboundCredentialsResponseMessage.java
@@ -34,7 +34,6 @@ import org.geant.shibboleth.plugin.openidvci.messaging.impl.CredentialOfferReque
 import org.geant.shibboleth.plugin.openidvci.messaging.impl.CredentialSuccessResponse;
 import org.geant.shibboleth.plugin.openidvci.messaging.impl.OpenIDVCICredentialsRequest;
 import org.geant.shibboleth.plugin.openidvci.profile.impl.stolen.AbstractOIDCResponseAction;
-import org.geant.shibboleth.plugin.openidvci.profile.logic.OpenIDVCITokenManipulationStrategy;
 import org.geant.shibboleth.plugin.openidvci.util.SelectiveDisclosureClaimSetUtil;
 import org.opensaml.messaging.context.navigate.ChildContextLookup;
 import org.opensaml.profile.action.ActionSupport;
@@ -61,7 +60,6 @@ import com.nimbusds.jose.util.Base64;
 import com.nimbusds.jwt.JWTClaimsSet;
 import com.nimbusds.jwt.JWTClaimsSet.Builder;
 import com.nimbusds.jwt.SignedJWT;
-import com.nimbusds.oauth2.sdk.ParseException;
 
 /**
  * Action forming {@link CredentialSuccessResponse}
@@ -185,10 +183,7 @@ public class FormOutboundCredentialsResponseMessage extends AbstractOIDCResponse
             CredentialsContext ctx = profileRequestContext.getInboundMessageContext()
                     .getSubcontext(CredentialsContext.class);
 
-            CredentialOfferRequestedCredential credential = CredentialOfferRequestedCredential
-                    .parse((String) getOidcResponseContext().getAuthorizationGrantClaimsSet().getClaimsSet()
-                            .getJSONObjectClaim(OpenIDVCITokenManipulationStrategy.PotentialClaims)
-                            .get(ctx.getCredentialIdentifier()));
+            CredentialOfferRequestedCredential credential = ctx.getCredential();
             log.info("Credentials stored credential {} {} ", ctx.getCredentialIdentifier(), credential.serialize());
             log.info("Key used, algorithm {}", signatureSigningParameters.getSignatureAlgorithm());
 
@@ -266,7 +261,7 @@ public class FormOutboundCredentialsResponseMessage extends AbstractOIDCResponse
             CredentialSuccessResponse response = new CredentialSuccessResponse(credentials);
             log.info("Setting response as {}", response.toOffer());
             profileRequestContext.ensureOutboundMessageContext().setMessage(response);
-        } catch (ParseException | JOSEException | JsonProcessingException | java.text.ParseException e) {
+        } catch (JOSEException | JsonProcessingException e) {
             log.error("{} Error occurred while parsing objects {}", getLogPrefix(), e);
             ActionSupport.buildEvent(profileRequestContext, EventIds.IO_ERROR);
         }
diff --git a/openid-vci-impl/src/main/java/org/geant/shibboleth/plugin/openidvci/profile/impl/ValidateCredentialOffering.java b/openid-vci-impl/src/main/java/org/geant/shibboleth/plugin/openidvci/profile/impl/ValidateCredentialOffering.java
index 9f5a48c..43ef451 100644
--- a/openid-vci-impl/src/main/java/org/geant/shibboleth/plugin/openidvci/profile/impl/ValidateCredentialOffering.java
+++ b/openid-vci-impl/src/main/java/org/geant/shibboleth/plugin/openidvci/profile/impl/ValidateCredentialOffering.java
@@ -79,7 +79,7 @@ public class ValidateCredentialOffering extends AbstractCredentialValidationActi
     @Override
     protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
         credentialConfIds.forEach(id -> {
-            if (!getCredentialConfigurations().getCredentialConfigurations().keySet().contains(id)) {
+            if (!getCredentialConfigurations().keySet().contains(id)) {
                 log.error("{} Requested credential configuration id {} is not supported", getLogPrefix(), id);
                 ActionSupport.buildEvent(profileRequestContext, OpenIDVCIEventIds.NO_CREDENTIALS_REQUEST);
                 return;
diff --git a/openid-vci-impl/src/main/java/org/geant/shibboleth/plugin/openidvci/profile/impl/ValidateRequestedCredential.java b/openid-vci-impl/src/main/java/org/geant/shibboleth/plugin/openidvci/profile/impl/ValidateRequestedCredential.java
index 5836ef9..5288bb2 100644
--- a/openid-vci-impl/src/main/java/org/geant/shibboleth/plugin/openidvci/profile/impl/ValidateRequestedCredential.java
+++ b/openid-vci-impl/src/main/java/org/geant/shibboleth/plugin/openidvci/profile/impl/ValidateRequestedCredential.java
@@ -16,33 +16,92 @@
 
 package org.geant.shibboleth.plugin.openidvci.profile.impl;
 
+import java.text.ParseException;
+import java.util.Map;
+import java.util.Set;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
 import javax.annotation.Nonnull;
 
+import org.geant.shibboleth.plugin.openidvci.credential.CredentialConfiguration;
 import org.geant.shibboleth.plugin.openidvci.messaging.context.CredentialsContext;
-import org.geant.shibboleth.plugin.openidvci.messaging.impl.OpenIDVCICredentialsRequest;
+import org.geant.shibboleth.plugin.openidvci.messaging.context.navigate.RequestCredentialConfigurationIdLookupFunction;
+import org.geant.shibboleth.plugin.openidvci.messaging.context.navigate.RequestCredentialIdentifierLookupFunction;
+import org.geant.shibboleth.plugin.openidvci.messaging.impl.CredentialOfferRequestedCredential;
 import org.geant.shibboleth.plugin.openidvci.profile.OpenIDVCIEventIds;
+import org.geant.shibboleth.plugin.openidvci.profile.logic.OpenIDVCITokenManipulationStrategy;
+import org.opensaml.messaging.context.MessageContext;
 import org.opensaml.profile.action.ActionSupport;
+import org.opensaml.profile.action.EventIds;
 import org.opensaml.profile.context.ProfileRequestContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import net.shibboleth.idp.profile.AbstractProfileAction;
-import net.shibboleth.shared.annotation.constraint.NonnullBeforeExec;
+import com.fasterxml.jackson.core.JsonProcessingException;
+
+import net.shibboleth.idp.plugin.oidc.op.messaging.context.OIDCAuthenticationResponseContext;
+import net.shibboleth.shared.logic.Constraint;
 
 /**
- * 
- * TBD actual validation. Merely stores either credential identifier or
- * configuration id value to {@link CredentialsContext}.
- * 
+ * Validates requested credential has a credential configuration. Both requested
+ * credential and the configuration is stored to {@link CredentialsContext}
  */
-public class ValidateRequestedCredential extends AbstractProfileAction {
+public class ValidateRequestedCredential extends AbstractCredentialValidationAction {
 
     /** Class logger. */
     @Nonnull
     private Logger log = LoggerFactory.getLogger(ValidateRequestedCredential.class);
 
-    @NonnullBeforeExec
-    private OpenIDVCICredentialsRequest request;
+    /**
+     * Strategy used to obtain the credential configuration id value from
+     * credentials request.
+     */
+    @Nonnull
+    private Function<ProfileRequestContext, String> requestCredentialConfigurationIdLookupStrategy;
+
+    /**
+     * Strategy used to obtain the credential identifier value from credentials
+     * request.
+     */
+    @Nonnull
+    private Function<ProfileRequestContext, String> requestCredentialIdentifierLookupStrategy;
+
+    private OIDCAuthenticationResponseContext oidcResponseContext;
+
+    /**
+     * Set the strategy used to obtain the credential configuration id value from
+     * credentials request.
+     * 
+     * @param strategy lookup strategy
+     */
+    public void setRequestCredentialConfigurationIdLookupStrategy(
+            @Nonnull final Function<ProfileRequestContext, String> strategy) {
+        ifInitializedThrowUnmodifiabledComponentException();
+        requestCredentialConfigurationIdLookupStrategy = Constraint.isNotNull(strategy,
+                "RequestCredentialConfigurationIdLookupStrategy lookup strategy cannot be null");
+    }
+
+    /**
+     * Set the strategy used to obtain the credential configuration id value from
+     * credentials request.
+     * 
+     * @param strategy lookup strategy
+     */
+    public void setRequestCredentialIdentifierLookupStrategy(
+            @Nonnull final Function<ProfileRequestContext, String> strategy) {
+        ifInitializedThrowUnmodifiabledComponentException();
+        requestCredentialIdentifierLookupStrategy = Constraint.isNotNull(strategy,
+                "RequestCredentialIdentifierLookupStrategy lookup strategy cannot be null");
+    }
+
+    /**
+     * Constructor.
+     */
+    public ValidateRequestedCredential() {
+        requestCredentialConfigurationIdLookupStrategy = new RequestCredentialConfigurationIdLookupFunction();
+        requestCredentialIdentifierLookupStrategy = new RequestCredentialIdentifierLookupFunction();
+    }
 
     /** {@inheritDoc} */
     @Override
@@ -50,26 +109,75 @@ public class ValidateRequestedCredential extends AbstractProfileAction {
         if (!super.doPreExecute(profileRequestContext)) {
             return false;
         }
-        if (profileRequestContext.getInboundMessageContext() != null && profileRequestContext.getInboundMessageContext()
-                .getMessage() instanceof OpenIDVCICredentialsRequest openIDVCICredentialsRequest) {
-            request = openIDVCICredentialsRequest;
-            return true;
-        } else {
-            log.error("{} No OpenIDVCICredentialsRequest as inbound message", getLogPrefix());
-            ActionSupport.buildEvent(profileRequestContext, OpenIDVCIEventIds.NO_CREDENTIALS_REQUEST);
+        final MessageContext outboundMessageCtx = profileRequestContext.getOutboundMessageContext();
+        if (outboundMessageCtx == null) {
+            log.error("{} No outbound message context", getLogPrefix());
+            ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_MSG_CTX);
+            return false;
+        }
+        oidcResponseContext = outboundMessageCtx.getSubcontext(OIDCAuthenticationResponseContext.class);
+        if (oidcResponseContext == null) {
+            log.error("{} No oidc response context", getLogPrefix());
+            ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_MSG_CTX);
             return false;
         }
+        return true;
     }
 
     /** {@inheritDoc} */
     @Override
     protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
 
+        String idInRequest = requestCredentialConfigurationIdLookupStrategy.apply(profileRequestContext);
+        if (idInRequest == null) {
+            // TOOD: Not sure if we should treat both values with same logic.
+            idInRequest = requestCredentialIdentifierLookupStrategy.apply(profileRequestContext);
+        }
+        CredentialConfiguration configuration = null;
+        if (idInRequest != null && getCredentialConfigurations().containsKey(idInRequest)) {
+            configuration = getCredentialConfigurations().get(idInRequest);
+        }
+        if (configuration == null) {
+            if (idInRequest != null) {
+                final String newId = idInRequest;
+                // Look for configurations that start as "id_"
+                Set<String> set = getCredentialConfigurations().keySet().stream().map(s -> newId.replaceFirst(s, ""))
+                        .filter(s -> s.startsWith("_") && s.lastIndexOf("_") == 0).collect(Collectors.toSet());
+                if (set.size() == 1) {
+                    configuration = getCredentialConfigurations().get(set.iterator().next());
+                }
+            }
+        }
+        if (configuration == null) {
+            log.error("{} No matching configuration found for requested credential {}", getLogPrefix(), idInRequest);
+            ActionSupport.buildEvent(profileRequestContext, OpenIDVCIEventIds.NO_CREDENTIALS_FOR_REQUEST);
+            return;
+        }
+        // look for claim that would match id and store it.
+        CredentialOfferRequestedCredential credential = null;
+        try {
+            Map<String, Object> potentialClaims = oidcResponseContext.getAuthorizationGrantClaimsSet().getClaimsSet()
+                    .getJSONObjectClaim(OpenIDVCITokenManipulationStrategy.PotentialClaims);
+            if (potentialClaims != null && potentialClaims.containsKey(idInRequest)) {
+                credential = CredentialOfferRequestedCredential.parse((String)potentialClaims.get(idInRequest));
+            }
+        } catch (ParseException | com.nimbusds.oauth2.sdk.ParseException | JsonProcessingException e) {
+            log.error("{} parsing failed", getLogPrefix(), e);
+            ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_PROFILE_CTX);
+            return;
+        }
+        if (credential == null) {
+            log.error("{} No matching credential content found for requested credential {}", getLogPrefix(),
+                    idInRequest);
+            ActionSupport.buildEvent(profileRequestContext, OpenIDVCIEventIds.NO_CREDENTIALS_FOR_REQUEST);
+            return;
+        }
+        // TODO: Move context creation to initialization phase
         CredentialsContext ctx = profileRequestContext.getInboundMessageContext()
                 .ensureSubcontext(CredentialsContext.class);
-        ctx.setCredentialIdentifier(
-                request.getCredentialConfigurationId() != null ? request.getCredentialConfigurationId()
-                        : request.getCredentialIdentifier());
-
+        ctx.setCredential(credential);
+        ctx.setConfiguration(configuration);
+        // TODO: This should be value in configuration. Fix.
+        ctx.setCredentialIdentifier(idInRequest);
     }
 }
\ No newline at end of file
diff --git a/openid-vci-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/openid/vci/credentials/credentials-beans.xml b/openid-vci-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/openid/vci/credentials/credentials-beans.xml
index dcece32..f75e960 100644
--- a/openid-vci-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/openid/vci/credentials/credentials-beans.xml
+++ b/openid-vci-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/openid/vci/credentials/credentials-beans.xml
@@ -31,7 +31,8 @@
   </bean>
   
   <bean id="ValidateRequestedCredential"
-        class="org.geant.shibboleth.plugin.openidvci.profile.impl.ValidateRequestedCredential" scope="prototype" />
+        class="org.geant.shibboleth.plugin.openidvci.profile.impl.ValidateRequestedCredential"
+        p:credentialsResource="%{idp.home}/metadata/verifiable-credentials.json" scope="prototype" />
         
   <bean id="ParseProof"
         class="org.geant.shibboleth.plugin.openidvci.profile.impl.ParseProof" scope="prototype" />

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the commits mailing list