[java-oidfed-common] 02/02: Add trust marks into the CLI and admin flow 'test-trust-chain-resolution'
Codeberg
noreply at shibboleth.net
Thu Jun 4 10:58:29 UTC 2026
This is an automated email from the git hooks/post-receive script.
codeberg pushed a commit to branch main
in repository java-oidfed-common.
View the commit online:
https://codeberg.org/Shibboleth/java-oidfed-common/commit/9b352fdc1992e79b3e31fb528340412dc4bf3084
commit 9b352fdc1992e79b3e31fb528340412dc4bf3084
Author: Henri Mikkonen <henri.mikkonen at iki.fi>
AuthorDate: Thu Jun 4 13:57:38 2026 +0300
Add trust marks into the CLI and admin flow 'test-trust-chain-resolution'
- The webflow resolves trust marks for each resolved trust chain and stores the details into ScratchContext
- Values are available in the view via 'trustMarkIds' and 'trustMarks': arrays with index matching 'trustChaintContext.getPolicyCompliantTrustChains()'
- Each trust_chain item in the response JSON contains an array of "trust_mark_ids"
- New option argument flags
- 'includeTrustMark', defaults to false
- Includes "trust_mark_details" item to each trust chain, containing a raw SignedJWT object
- 'remoteTrustMarkValidation', defaults to false
- To perform remote trust mark validation
---
.../test-trust-chain-resolution-beans.xml | 34 ++++++++++++++++++++++
.../test-trust-chain-resolution-flow.xml | 29 ++++++++++++++++--
.../admin/oidfed/test-trust-chain-resolution.vm | 22 +++++++++++---
.../cli/TestTrustChainResolutionArguments.java | 23 ++++++++++++++-
4 files changed, 100 insertions(+), 8 deletions(-)
diff --git a/oidfed-common-conf-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/admin/oidfed/test-trust-chain-resolution/test-trust-chain-resolution-beans.xml b/oidfed-common-conf-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/admin/oidfed/test-trust-chain-resolution/test-trust-chain-resolution-beans.xml
index ba8058a..7a3d6ac 100644
--- a/oidfed-common-conf-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/admin/oidfed/test-trust-chain-resolution/test-trust-chain-resolution-beans.xml
+++ b/oidfed-common-conf-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/admin/oidfed/test-trust-chain-resolution/test-trust-chain-resolution-beans.xml
@@ -47,6 +47,40 @@
c:expression="'true'.equalsIgnoreCase(#custom.get().getParameter('fallbackToLocalResolution'))"
p:customObject-ref="shibboleth.HttpServletRequestSupplier" />
+ <bean id="TrustChainCandidatesExist" parent="shibboleth.Conditions.Expression"
+ c:expression="#input.ensureInboundMessageContext().containsSubcontext(T(net.shibboleth.oidfed.profile.context.RelyingPartyTrustChainContext)) and #input.ensureInboundMessageContext().ensureSubcontext(T(net.shibboleth.oidfed.profile.context.RelyingPartyTrustChainContext)).getPolicyCompliantTrustChains() != null and #input.ensureInboundMessageContext().ensureSubcontext(T(net.shibboleth.oidfed.profile.context.RelyingPartyTrustChainContext)).getPolicyCompliantTrustChains().size() > # [...]
+
+ <bean id="SelectTrustChain" class="net.shibboleth.oidfed.profile.impl.SelectTrustChain"
+ scope="prototype"/>
+
+ <bean id="ResolveTrustMarks" class="net.shibboleth.oidfed.profile.impl.ResolveTrustMarks"
+ scope="prototype"
+ p:trustChainCache-ref="#{'%{idp.oidfed.authorize.TrustChainMetadataCache:shibboleth.oidfed.TrustChainMetadataCache}'.trim()}"
+ p:trustMarkClaimsValidationLookupStrategy="#{getObject('shibboleth.oidfed.TrustMarkClaimsValidationLookupStrategy') ?: getObject('DefaultTrustMarkClaimsValidationLookupStrategy')}"
+ p:delegatedTrustMarkClaimsValidationLookupStrategy="#{getObject('shibboleth.oidfed.DelegatedTrustMarkClaimsValidationLookupStrategy') ?: getObject('DefaultDelegatedTrustMarkClaimsValidationLookupStrategy')}"
+ p:trustEngine-ref="shibboleth.oidfed.DefaultEntityConfigurationTrustEngine"
+ p:delegationTrustEngine-ref="shibboleth.oidfed.DefaultDelegatedTrustMarkTrustEngine">
+ <property name="trustChainTrustMarksParsingStrategy">
+ <bean class="net.shibboleth.oidfed.profile.navigate.DefaultTrustChainTrustMarksParsingStrategy"/>
+ </property>
+ <property name="trustedTrustMarkIssuersLookupStrategy">
+ <bean class="net.shibboleth.oidfed.profile.navigate.DefaultTrustChainTrustedTrustMarkIssuersLookupStrategy"/>
+ </property>
+ <property name="trustedTrustMarkOwnersLookupStrategy">
+ <bean class="net.shibboleth.oidfed.profile.navigate.DefaultTrustChainTrustedTrustMarkOwnersLookupStrategy"/>
+ </property>
+ </bean>
+
+ <bean id="ValidateTrustMarks" class="net.shibboleth.oidfed.profile.impl.ValidateTrustMarks"
+ scope="prototype"
+ p:trustMarkStatusCache-ref="#{'%{idp.oidfed.authorize.TrustMarkStatusMetadataCache:shibboleth.oidfed.TrustMarkStatusMetadataCache}'.trim()}">
+ <property name="remoteTrustMarkValidationCondition">
+ <bean parent="shibboleth.Conditions.Expression"
+ c:expression="'true'.equalsIgnoreCase(#custom.get().getParameter('remoteTrustMarkValidation'))"
+ p:customObject-ref="shibboleth.HttpServletRequestSupplier" />
+ </property>
+ </bean>
+
<bean id="oidc.messageEncoderFactory"
class="net.shibboleth.oidc.profile.encoding.impl.OIDCResponseEncoderFactory"
p:messageEncoder-ref="oidc.nimbusEncoder" scope="prototype" />
diff --git a/oidfed-common-conf-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/admin/oidfed/test-trust-chain-resolution/test-trust-chain-resolution-flow.xml b/oidfed-common-conf-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/admin/oidfed/test-trust-chain-resolution/test-trust-chain-resolution-flow.xml
index 8e6caf6..69ee418 100644
--- a/oidfed-common-conf-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/admin/oidfed/test-trust-chain-resolution/test-trust-chain-resolution-flow.xml
+++ b/oidfed-common-conf-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/admin/oidfed/test-trust-chain-resolution/test-trust-chain-resolution-flow.xml
@@ -12,6 +12,8 @@
<evaluate expression="T(net.shibboleth.shared.primitive.StringSupport).trimOrNull(externalContext.getNativeRequest().getParameter('includeJWT'))" result="flowScope.includeJWT" />
<evaluate expression="T(net.shibboleth.shared.primitive.StringSupport).trimOrNull(externalContext.getNativeRequest().getParameter('includeMetadata'))" result="flowScope.includeMetadata" />
<evaluate expression="T(net.shibboleth.shared.primitive.StringSupport).trimOrNull(externalContext.getNativeRequest().getParameter('useResolverApi'))" result="flowScope.useResolverApi" />
+ <evaluate expression="T(net.shibboleth.shared.primitive.StringSupport).trimOrNull(externalContext.getNativeRequest().getParameter('includeTrustMark'))" result="flowScope.includeTrustMark" />
+ <evaluate expression="T(net.shibboleth.shared.primitive.StringSupport).trimOrNull(externalContext.getNativeRequest().getParameter('remoteTrustMarkValidation'))" result="flowScope.remoteTrustMarkValidation" />
</on-start>
<action-state id="InitializeProfileRequestContext">
@@ -30,18 +32,39 @@
<evaluate expression="CheckAccess" />
<evaluate expression="'proceed'" />
<transition on="proceed" to="ChooseResolutionMethod">
- <set name="flowScope.transitionAfterTrustChainResolution" value="'ResponseView'" />
+ <set name="flowScope.transitionAfterTrustChainResolution" value="'CheckIfTrustChainCandidatesExist'" />
<set name="flowScope.transitionOnNoTrustChainsResolved" value="'ResponseView'" />
- <evaluate expression="opensamlProfileRequestContext.ensureInboundMessageContext()"/>
+ <evaluate expression="opensamlProfileRequestContext.ensureInboundMessageContext().ensureSubcontext(T(net.shibboleth.oidfed.profile.context.RelyingPartyTrustChainContext)).setRejectedTrustChains(new java.util.ArrayList())"/>
+ <evaluate expression="opensamlProfileRequestContext.ensureSubcontext(T(org.opensaml.messaging.context.ScratchContext)).getMap().put('TestTrustChainResolution.TrustMarks', new java.util.ArrayList())"/>
+ <evaluate expression="opensamlProfileRequestContext.ensureSubcontext(T(org.opensaml.messaging.context.ScratchContext)).getMap().put('TestTrustChainResolution.TrustMarkIds', new java.util.ArrayList())"/>
</transition>
</action-state>
-
+
+ <decision-state id="CheckIfTrustChainCandidatesExist">
+ <if test="TrustChainCandidatesExist.test(opensamlProfileRequestContext)"
+ then="ProcessTrustChainCandidate" else="ResponseView" />
+ </decision-state>
+
+ <action-state id="ProcessTrustChainCandidate">
+ <evaluate expression="SelectTrustChain" />
+ <evaluate expression="ResolveTrustMarks" />
+ <evaluate expression="ValidateTrustMarks" />
+ <evaluate expression="'proceed'" />
+ <transition on="proceed" to="CheckIfTrustChainCandidatesExist">
+ <evaluate expression="opensamlProfileRequestContext.ensureInboundMessageContext().getSubcontext(T(net.shibboleth.oidfed.profile.context.RelyingPartyTrustChainContext)).getRejectedTrustChains().add(opensamlProfileRequestContext.ensureInboundMessageContext().getSubcontext(T(net.shibboleth.oidfed.profile.context.RelyingPartyTrustChainContext)).getSelectedTrustChain().getTrustChain())" />
+ <evaluate expression="opensamlProfileRequestContext.ensureSubcontext(T(org.opensaml.messaging.context.ScratchContext)).getMap().get('TestTrustChainResolution.TrustMarks').add(opensamlProfileRequestContext.ensureInboundMessageContext().getSubcontext(T(net.shibboleth.oidfed.profile.context.RelyingPartyTrustChainContext)).getVerifiedTrustMarks().get(entityID))"/>
+ <evaluate expression="opensamlProfileRequestContext.ensureSubcontext(T(org.opensaml.messaging.context.ScratchContext)).getMap().get('TestTrustChainResolution.TrustMarkIds').add(opensamlProfileRequestContext.ensureInboundMessageContext().getSubcontext(T(net.shibboleth.oidfed.profile.context.RelyingPartyTrustChainContext)).getVerifiedTrustMarkIds().get(entityID))"/>
+ </transition>
+ </action-state>
+
<end-state id="ResponseView" view="admin/oidfed/test-trust-chain-resolution">
<on-entry>
<evaluate expression="WriteAuditLog" />
<evaluate expression="environment" result="requestScope.environment" />
<evaluate expression="opensamlProfileRequestContext" result="requestScope.profileRequestContext" />
<evaluate expression="opensamlProfileRequestContext.ensureInboundMessageContext().ensureSubcontext(T(net.shibboleth.oidfed.profile.context.RelyingPartyTrustChainContext))" result="requestScope.trustChaintContext" />
+ <evaluate expression="opensamlProfileRequestContext.ensureSubcontext(T(org.opensaml.messaging.context.ScratchContext)).getMap().get('TestTrustChainResolution.TrustMarks')" result="requestScope.trustMarks" />
+ <evaluate expression="opensamlProfileRequestContext.ensureSubcontext(T(org.opensaml.messaging.context.ScratchContext)).getMap().get('TestTrustChainResolution.TrustMarkIds')" result="requestScope.trustMarkIds" />
<evaluate expression="T(org.opensaml.core.xml.util.XMLObjectSupport)" result="requestScope.XMLObjectSupport" />
<evaluate expression="T(net.shibboleth.shared.xml.SerializeSupport)" result="requestScope.SerializeSupport" />
<evaluate expression="T(net.shibboleth.shared.codec.HTMLEncoder)" result="requestScope.encoder" />
diff --git a/oidfed-common-conf-impl/src/main/resources/META-INF/net/shibboleth/idp/views/admin/oidfed/test-trust-chain-resolution.vm b/oidfed-common-conf-impl/src/main/resources/META-INF/net/shibboleth/idp/views/admin/oidfed/test-trust-chain-resolution.vm
index dce384c..0d8017d 100644
--- a/oidfed-common-conf-impl/src/main/resources/META-INF/net/shibboleth/idp/views/admin/oidfed/test-trust-chain-resolution.vm
+++ b/oidfed-common-conf-impl/src/main/resources/META-INF/net/shibboleth/idp/views/admin/oidfed/test-trust-chain-resolution.vm
@@ -7,15 +7,19 @@
## response - HttpServletResponse
## profileRequestContext
## trustChaintContext
+## entityID
## includeJWT
## includeMetadata
+## includeTrustMark
+## trustMarks
+## trustMarkIds
## SerializeSupport
## environment - Spring Environment object for property resolution
## custom - arbitrary object injected by deployer
##
[#if ($trustChaintContext and $trustChaintContext.getPolicyCompliantTrustChains() and !$trustChaintContext.getPolicyCompliantTrustChains().isEmpty())
-
-#foreach ($policyCompliantChain in $trustChaintContext.getPolicyCompliantTrustChains())
+#set ($index = 0)
+#foreach ($policyCompliantChain in $trustChaintContext.getPolicyCompliantTrustChains()) #set ($index = $index + 1)
{
"trust_chain" : [
#foreach ($entityStatement in $policyCompliantChain.getTrustChain())
@@ -37,13 +41,23 @@
#foreach ($metadataKey in $policyCompliantChain.getMetadata().getAllClaims().keySet())
"$metadataKey"#if( $foreach.hasNext ),#end
#end
- ]#if($includeMetadata),
+ ],#if($includeMetadata)
"metadata_details" : [
#foreach ($metadataKey in $policyCompliantChain.getMetadata().getAllClaims().keySet())
"$metadataKey": $policyCompliantChain.getMetadata().getAllClaims().get($metadataKey)#if( $foreach.hasNext ),#end
#end
- ]
+ ],
+#end
+ "trust_mark_ids" : [
+#foreach ($trustMarkId in $trustMarkIds.get($index - 1))
+ "$trustMarkId"#if( $foreach.hasNext ),#end
+#end
+ ]#if($includeTrustMark),
+ "trust_mark_details" : [
+#foreach ($trustMark in $trustMarks.get($index - 1))
+ "$trustMark.serialize()"#if( $foreach.hasNext ),#end
#end
+ ]#end
}#if( $foreach.hasNext ),#end
#end
#end]
diff --git a/oidfed-common-impl/src/main/java/net/shibboleth/oidfed/cli/TestTrustChainResolutionArguments.java b/oidfed-common-impl/src/main/java/net/shibboleth/oidfed/cli/TestTrustChainResolutionArguments.java
index e284642..a78208c 100644
--- a/oidfed-common-impl/src/main/java/net/shibboleth/oidfed/cli/TestTrustChainResolutionArguments.java
+++ b/oidfed-common-impl/src/main/java/net/shibboleth/oidfed/cli/TestTrustChainResolutionArguments.java
@@ -48,6 +48,12 @@ public class TestTrustChainResolutionArguments extends AbstractCommandLineArgume
/** The URL parameter name for the flag to fallback to local resolution if resolver API fails. */
public static final String URL_PARAM_FALLBACK_TO_LOCAL = "fallbackToLocalResolution";
+ /** The URL parameter name for the flag to signal full trust mark details to be included. */
+ public static final String URL_PARAM_INCLUDE_TRUST_MARK = "includeTrustMark";
+
+ /** The URL parameter name for the flag to signal remote trust mark validation. */
+ public static final String URL_PARAM_REMOTE_TRUST_MARK_VALIDATION = "remoteTrustMarkValidation";
+
/** Metadata policy to embed in the token. */
@Parameter(names = {"-id", "--entityID"}, required = false, description = "Entity ID to be resolved")
@Nullable private String entityId;
@@ -72,6 +78,16 @@ public class TestTrustChainResolutionArguments extends AbstractCommandLineArgume
description = "Flag to fallback to local resolution if resolve API resolution fails")
private boolean fallbackToLocal;
+ /** Flag to signal full trust mark details to be included. */
+ @Parameter(names = {"-trustMark", "--includeTrustMark"}, required = false,
+ description = "Flag to include raw trust mark JWTs in the response")
+ private boolean includeTrustMark;
+
+ /** Flag to signal remote trust mark validation. */
+ @Parameter(names = {"-trustMarkValidation", "--remoteTrustMarkValidation"}, required = false,
+ description = "Flag to do remote trust mark validation")
+ private boolean remoteTrustMarkValidation;
+
/** {@inheritDoc} */
@Override
public void validate() {
@@ -105,8 +121,13 @@ public class TestTrustChainResolutionArguments extends AbstractCommandLineArgume
if (fallbackToLocal) {
builder.append("&" + URL_PARAM_FALLBACK_TO_LOCAL + "=true");
}
+ if (includeTrustMark) {
+ builder.append("&" + URL_PARAM_INCLUDE_TRUST_MARK + "=true");
+ }
+ if (remoteTrustMarkValidation) {
+ builder.append("&" + URL_PARAM_REMOTE_TRUST_MARK_VALIDATION + "=true");
+ }
-
} catch (final UnsupportedEncodingException e) {
// UTF-8 is a required encoding.
throw new RuntimeException("URL encoding failed", e);
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list