[java-idp-plugin-vci] branch dev/REFRESH updated: Token endpoint resolution example

Codeberg noreply at shibboleth.net
Wed Nov 4 12:13:32 UTC 2026


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

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

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

The following commit(s) were added to refs/heads/dev/REFRESH by this push:
     new cbd4a65  Token endpoint resolution example
cbd4a65 is described below

commit cbd4a652407476b0259907bd319bbb86d777a753
Author: Janne Lauros <janne.lauros at csc.fi>
AuthorDate: Wed Nov 4 14:13:17 2026 +0200

    Token endpoint resolution example
---
 README.md | 50 +++++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 45 insertions(+), 5 deletions(-)

diff --git a/README.md b/README.md
index 15fa6f2..910169d 100644
--- a/README.md
+++ b/README.md
@@ -4522,6 +4522,9 @@ An attribute reaches a credential in one of two ways:
 Either way, the access token carries the credentials of the grant, limited to its scope and
 `authorization_details`. Use one way per attribute.
 
+`resolveAttributes="false"` on **OpenID.VCI.Token** turns resolution at the token endpoint off.
+Credentials then come only from `idp.oidc.encodedAttributes`.
+
 #### Keeping the authorization code small
 
 The authorization code travels to the wallet in the redirect URL. Every attribute in
@@ -4540,13 +4543,50 @@ For the attribute of [Step 1](#authorization-code-flow), leave it out of *conf/o
 The policy of *conf/attribute-filter.xml* stays as it is. It releases the attribute to the wallet
 at both endpoints.
 
+#### Values of the login
+
 The token endpoint has no login. The resolver gets the user's principal name from the grant, but no
-result of an authentication, so an attribute that comes from the login itself, a claim of an
-upstream identity provider for example, cannot be resolved there. Keep such attributes in
-`idp.oidc.encodedAttributes`.
+result of an authentication, so a value that comes from the login itself, a claim of an upstream
+identity provider for example, cannot be resolved there unless it is already encoded to token,
+in practice the authorization code.
 
-`resolveAttributes="false"` on **OpenID.VCI.Token** turns resolution at the token endpoint off.
-Credentials then come only from `idp.oidc.encodedAttributes`.
+Below, the affiliation of the diploma of Step 1 comes from the upstream identity provider at login
+and we assume it has been encoded as claim `upstream_affiliation` to authorization code. The other
+values come from an imaginary `myLDAP` data connector. `resolutionPhases` limits the definition to the token
+endpoint, flow `openid/vci/token`:
+
+```xml
+<AttributeDefinition id="GeantIncubatorDiploma" xsi:type="ScriptedAttribute"
+        resolutionPhases="openid/vci/token">
+    <InputDataConnector ref="myLDAP" attributeNames="mail eduPersonPrincipalName givenName sn" />
+    <Script><![CDATA[
+        var ResponseContext = Java.type("net.shibboleth.idp.plugin.oidc.op.messaging.context.OIDCAuthenticationResponseContext");
+        var TokenClaimsContext = Java.type("net.shibboleth.idp.plugin.oidc.op.messaging.context.OIDCAuthenticationResponseTokenClaimsContext");
+        var responseCtx = profileContext.getOutboundMessageContext().getSubcontext(ResponseContext.class);
+        var claimsCtx = responseCtx != null ? responseCtx.getSubcontext(TokenClaimsContext.class) : null;
+        var affiliation = null;
+        if (claimsCtx != null) {
+            affiliation = claimsCtx.getUserinfoClaims().getClaim("upstream_affiliation");
+            if (affiliation == null) {
+                affiliation = claimsCtx.getClaims().getClaim("upstream_affiliation");
+            }
+        }
+        var claims = [
+            {"path": ["diploma"], "value": "Scrum Master"},
+            {"path": ["mail"], "value": String(mail.getValues().get(0))},
+            {"path": ["eppn"], "value": String(eduPersonPrincipalName.getValues().get(0))},
+            {"path": ["givenName"], "value": String(givenName.getValues().get(0))},
+            {"path": ["familyName"], "value": String(sn.getValues().get(0))}
+        ];
+        if (affiliation != null) {
+            claims.push({"path": ["affiliation"], "value": String(affiliation)});
+        }
+        GeantIncubatorDiploma.addValue(JSON.stringify(claims));
+    ]]></Script>
+    <AttributeEncoder xsi:type="oidc:OIDCString" name="GeantIncubatorDiploma_SDJWT" />
+    <AttributeEncoder xsi:type="oidc:OIDCString" name="GeantIncubatorDiploma_W3C" />
+</AttributeDefinition>
+```
 
 ## Reference
 

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


More information about the commits mailing list