[java-idp-plugin-vci] 01/06: Fetch ready made access token from oidc response context.
Codeberg
noreply at shibboleth.net
Tue Dec 9 07:21:56 UTC 2025
This is an automated email from the git hooks/post-receive script.
codeberg pushed a commit to branch dev/DPOP
in repository java-idp-plugin-vci.
View the commit online:
https://codeberg.org/Shibboleth/java-idp-plugin-vci/commit/e73cd66feac4b0761859ef378b6722cb8fce153d
commit e73cd66feac4b0761859ef378b6722cb8fce153d
Author: jlauros <janne.lauros at csc.fi>
AuthorDate: Tue Dec 9 08:40:46 2025 +0200
Fetch ready made access token from oidc response context.
---
.../impl/FormOutboundTokenResponseMessage.java | 203 +--------------------
1 file changed, 9 insertions(+), 194 deletions(-)
diff --git a/openid-vci-impl/src/main/java/org/geant/shibboleth/plugin/openidvci/profile/impl/FormOutboundTokenResponseMessage.java b/openid-vci-impl/src/main/java/org/geant/shibboleth/plugin/openidvci/profile/impl/FormOutboundTokenResponseMessage.java
index f704448..bf59088 100644
--- a/openid-vci-impl/src/main/java/org/geant/shibboleth/plugin/openidvci/profile/impl/FormOutboundTokenResponseMessage.java
+++ b/openid-vci-impl/src/main/java/org/geant/shibboleth/plugin/openidvci/profile/impl/FormOutboundTokenResponseMessage.java
@@ -16,25 +16,15 @@
package org.geant.shibboleth.plugin.openidvci.profile.impl;
-import java.io.IOException;
-import java.time.Duration;
-import java.time.Instant;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import java.util.function.Function;
import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-import org.geant.shibboleth.plugin.openidvci.config.OpenIDVCIConfiguration;
import org.geant.shibboleth.plugin.openidvci.messaging.context.TokenContext;
-import org.geant.shibboleth.plugin.openidvci.messaging.context.navigate.AuthorizationDetailsLookupFunction;
import org.geant.shibboleth.plugin.openidvci.messaging.impl.AbstractOpenIDVCITokenResponseAction;
-import org.geant.shibboleth.plugin.openidvci.messaging.impl.OpenIDVCIAuthorizationDetail;
import org.geant.shibboleth.plugin.openidvci.messaging.impl.OpenIDVCITokenRequest;
-import org.geant.shibboleth.plugin.openidvci.storage.CredentialOfferObject;
-import org.opensaml.messaging.context.navigate.ChildContextLookup;
import org.opensaml.profile.action.ActionSupport;
import org.opensaml.profile.action.EventIds;
import org.opensaml.profile.context.ProfileRequestContext;
@@ -44,167 +34,26 @@ import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.nimbusds.oauth2.sdk.AccessTokenResponse;
-import com.nimbusds.oauth2.sdk.token.AccessToken;
-import com.nimbusds.oauth2.sdk.token.BearerAccessToken;
-import com.nimbusds.oauth2.sdk.Scope;
import com.nimbusds.oauth2.sdk.token.Tokens;
-import net.shibboleth.idp.plugin.oidc.op.token.support.AccessTokenClaimsSet;
-import net.shibboleth.idp.profile.IdPEventIds;
-import net.shibboleth.profile.config.ProfileConfiguration;
-import net.shibboleth.profile.context.RelyingPartyContext;
-import net.shibboleth.profile.context.navigate.IssuerLookupFunction;
-import net.shibboleth.shared.annotation.ParameterName;
import net.shibboleth.shared.annotation.constraint.NonnullBeforeExec;
-import net.shibboleth.shared.logic.Constraint;
-import net.shibboleth.shared.security.DataSealer;
-import net.shibboleth.shared.security.DataSealerException;
-import net.shibboleth.shared.security.IdentifierGenerationStrategy;
-import net.shibboleth.shared.security.impl.SecureRandomIdentifierGenerationStrategy;
-/**
- * Action forms Token Response {@link AccessToken}. Token is always of opaque
- * type. Token has no user identifying information like principal, for now. It
- * would need to come as part of credential offer request to be populated here.
- */
public class FormOutboundTokenResponseMessage extends AbstractOpenIDVCITokenResponseAction {
/** Class logger. */
@Nonnull
private Logger log = LoggerFactory.getLogger(FormOutboundTokenResponseMessage.class);
- /** The generator to use. */
- @Nullable
- private IdentifierGenerationStrategy idGenerator;
-
- /** Strategy used to locate the {@link IdentifierGenerationStrategy} to use. */
- @Nonnull
- private Function<ProfileRequestContext, IdentifierGenerationStrategy> idGeneratorLookupStrategy;
-
- /** Data sealer for handling access token. */
- @Nonnull
- private final DataSealer dataSealer;
-
- /**
- * Strategy used to locate the {@link RelyingPartyContext} associated with a
- * given {@link ProfileRequestContext}.
- */
- @Nonnull
- private Function<ProfileRequestContext, RelyingPartyContext> relyingPartyContextLookupStrategy;
-
- /** Relying party context. */
- private RelyingPartyContext rpCtx;
-
- /** Strategy used to obtain the response issuer value. */
- @Nonnull
- private Function<ProfileRequestContext, String> issuerLookupStrategy;
-
- /** Access Token lifetime. */
- private Duration accessTokenLifetime;
-
@NonnullBeforeExec
private TokenContext tokenContext;
- /** Strategy used to locate the {@link OpenIDVCIAuthorizationDetail} to use. */
- @Nonnull
- private Function<ProfileRequestContext, List<OpenIDVCIAuthorizationDetail>> authorizationDetailsStrategy;
-
- /**
- * Set the strategy used to locate the {@link OpenIDVCIAuthorizationDetail} to
- * use.
- *
- * @param strategy lookup strategy
- */
- public void setAuthorizationDetailsLookupStrategy(
- @Nonnull final Function<ProfileRequestContext, List<OpenIDVCIAuthorizationDetail>> strategy) {
- authorizationDetailsStrategy = Constraint.isNotNull(strategy,
- "AuthorizationDetailsLookupStrategy lookup strategy cannot be null");
- }
-
- public FormOutboundTokenResponseMessage(@Nonnull @ParameterName(name = "sealer") final DataSealer sealer) {
- dataSealer = Constraint.isNotNull(sealer, "DataSealer cannot be null");
- idGeneratorLookupStrategy = new Function<ProfileRequestContext, IdentifierGenerationStrategy>() {
- public IdentifierGenerationStrategy apply(ProfileRequestContext input) {
- return new SecureRandomIdentifierGenerationStrategy();
- }
- };
- issuerLookupStrategy = (Function<ProfileRequestContext, String>) new IssuerLookupFunction();
- relyingPartyContextLookupStrategy = new ChildContextLookup<>(RelyingPartyContext.class);
- authorizationDetailsStrategy = new AuthorizationDetailsLookupFunction();
- }
-
- /**
- * Set the strategy used to locate the {@link IdentifierGenerationStrategy} to
- * use.
- *
- * @param strategy lookup strategy
- */
- public void setIdentifierGeneratorLookupStrategy(
- @Nonnull final Function<ProfileRequestContext, IdentifierGenerationStrategy> strategy) {
- checkSetterPreconditions();
-
- idGeneratorLookupStrategy = Constraint.isNotNull(strategy,
- "IdentifierGenerationStrategy lookup strategy cannot be null");
- }
-
- /**
- * Set the strategy used to locate the {@link RelyingPartyContext} associated
- * with a given {@link ProfileRequestContext}.
- *
- * @param strategy strategy used to locate the {@link RelyingPartyContext}
- * associated with a given {@link ProfileRequestContext}
- */
- public void setRelyingPartyContextLookupStrategy(
- @Nonnull final Function<ProfileRequestContext, RelyingPartyContext> strategy) {
- checkSetterPreconditions();
-
- relyingPartyContextLookupStrategy = Constraint.isNotNull(strategy,
- "RelyingPartyContext lookup strategy cannot be null");
- }
-
- /**
- * 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");
- }
-
- // Checkstyle: CyclomaticComplexity OFF
/** {@inheritDoc} */
@Override
protected boolean doPreExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
if (!super.doPreExecute(profileRequestContext)) {
return false;
}
- idGenerator = idGeneratorLookupStrategy.apply(profileRequestContext);
- if (idGenerator == null) {
- log.error("{} No identifier generation strategy", getLogPrefix());
- ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_PROFILE_CTX);
- return false;
- }
- rpCtx = relyingPartyContextLookupStrategy.apply(profileRequestContext);
- if (rpCtx == null) {
- log.error("{} No relying party context associated with this profile request", getLogPrefix());
- ActionSupport.buildEvent(profileRequestContext, IdPEventIds.INVALID_RELYING_PARTY_CTX);
- return false;
- }
- final ProfileConfiguration pc = rpCtx.getProfileConfig();
- if (pc != null && pc instanceof OpenIDVCIConfiguration cfg) {
- accessTokenLifetime = cfg.getAccessTokenLifetime(profileRequestContext);
- } else {
- log.error("{} No oidc profile configuration associated with this profile request", getLogPrefix());
- ActionSupport.buildEvent(profileRequestContext, IdPEventIds.INVALID_RELYING_PARTY_CTX);
- return false;
- }
- if (profileRequestContext.getInboundMessageContext() == null) {
- log.error("{} No inbound message context", getLogPrefix());
- ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_PROFILE_CTX);
- return false;
- }
tokenContext = profileRequestContext.getInboundMessageContext().getSubcontext(TokenContext.class);
if (tokenContext == null) {
log.error("{} No token context", getLogPrefix());
@@ -223,49 +72,15 @@ public class FormOutboundTokenResponseMessage extends AbstractOpenIDVCITokenResp
ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_MSG_CTX);
return;
}
- try {
- CredentialOfferObject credentialOffer = tokenContext.getCredentialOfferObject();
- AccessTokenResponse response = null;
- AccessTokenClaimsSet claimsSet = null;
- if (credentialOffer != null) {
- // TODO: Set proper access token values!
- claimsSet = new AccessTokenClaimsSet.Builder()
- .setIssuer(issuerLookupStrategy.apply(profileRequestContext))
- .setClientID(credentialOffer.getClientID()).setJWTID(idGenerator).setIssuedAt(Instant.now())
- .setAuthenticationTime(Instant.now()).setPrincipal("dummy")
- .setSubject(credentialOffer.serialize()).setScope(new Scope("openid"))
- .setDlClaimsUI(tokenContext.getPotentialCredentials())
- .setExpiresAt(Instant.now().plus(accessTokenLifetime)).build();
- log.info("Serialized access token {}", claimsSet.serialize());
- AccessToken accesToken = new BearerAccessToken(claimsSet.serialize(dataSealer),
- accessTokenLifetime.toSeconds(), null);
-
- if (tokenContext.getResponseAuthorizationDetails() != null) {
- Map<String, Object> params = new HashMap<>();
- params.put("authorization_details", new ObjectMapper().convertValue(
- tokenContext.getResponseAuthorizationDetails(), new TypeReference<List<Object>>() {
- }));
- response = new AccessTokenResponse(new Tokens(accesToken, null), params);
- } else {
- response = new AccessTokenResponse(new Tokens(accesToken, null));
- }
- } else if (getOidcResponseContext().getAuthorizationGrantClaimsSet() != null) {
- if (tokenContext.getResponseAuthorizationDetails() != null) {
- Map<String, Object> params = new HashMap<>();
- params.put("authorization_details", new ObjectMapper().convertValue(
- tokenContext.getResponseAuthorizationDetails(), new TypeReference<List<Object>>() {
- }));
- response = new AccessTokenResponse(new Tokens(getOidcResponseContext().getAccessToken(), null),
- params);
- } else {
- response = new AccessTokenResponse(new Tokens(getOidcResponseContext().getAccessToken(), null));
- }
- }
- profileRequestContext.ensureOutboundMessageContext().setMessage(response);
- return;
- } catch (IOException | DataSealerException e) {
- log.error("{} Error occurred while handling CredentialOfferObject {}", getLogPrefix(), e);
- ActionSupport.buildEvent(profileRequestContext, EventIds.IO_ERROR);
+ Map<String, Object> params = null;
+ if (tokenContext.getResponseAuthorizationDetails() != null) {
+ params = new HashMap<>();
+ params.put("authorization_details", new ObjectMapper()
+ .convertValue(tokenContext.getResponseAuthorizationDetails(), new TypeReference<List<Object>>() {
+ }));
}
+ profileRequestContext.ensureOutboundMessageContext().setMessage(
+ new AccessTokenResponse(new Tokens(getOidcResponseContext().getAccessToken(), null), params));
+ return;
}
}
\ No newline at end of file
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list