[java-oidfed-common] branch main updated: Refactor trust mark fetching and validation
Codeberg
noreply at shibboleth.net
Wed Sep 23 17:03:49 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/1f34880826278f79670cb98f8059825df86cc897
The following commit(s) were added to refs/heads/main by this push:
new 1f34880 Refactor trust mark fetching and validation
1f34880 is described below
commit 1f34880826278f79670cb98f8059825df86cc897
Author: Henri Mikkonen <henri.mikkonen at iki.fi>
AuthorDate: Wed Sep 23 20:03:08 2026 +0300
Refactor trust mark fetching and validation
- Harmonise the trust mark issuer configuration fetching and validation
- Similar now between trust mark fetching for entity configuration and trust mark resolution for other entities
- Configurable for the flows
- idp.oidfed.admin.resolvertest.EntityConfigurationMetadataCache
- idp.oidfed.admin.resolvertest.LocalTrustAnchorsMetadataCache
- idp.oidfed.resolveEntity.EntityConfigurationMetadataCache
- idp.oidfed.resolveEntity.LocalTrustAnchorsMetadataCache
- Wire properties for requiring trust_mark_issuers from the trust anchor, defaults to shibboleth.Conditions.TRUE
- idp.oidfed.admin.resolvertest.TrustedTrustMarkIssuersOnlyCondition
- idp.oidfed.resolveEntity.TrustedTrustMarkIssuersOnlyCondition
---
.../META-INF/net.shibboleth.idp/postconfig.xml | 60 ++++----
.../test-trust-chain-resolution-beans.xml | 20 ++-
.../oidfed/resolve-entity/resolve-entity-beans.xml | 20 ++-
...stMarkIssuerConfigurationFetchingStrategy.java} | 60 +++-----
...ustMarkValidationCriteriaSetLookupFunction.java | 152 +++------------------
.../oidfed/profile/impl/ResolveTrustMarks.java | 57 ++++----
.../oidfed/conf/oidfed/oidfed.properties | 6 +
7 files changed, 143 insertions(+), 232 deletions(-)
diff --git a/oidfed-common-conf-impl/src/main/resources/META-INF/net.shibboleth.idp/postconfig.xml b/oidfed-common-conf-impl/src/main/resources/META-INF/net.shibboleth.idp/postconfig.xml
index 42bd010..155c061 100644
--- a/oidfed-common-conf-impl/src/main/resources/META-INF/net.shibboleth.idp/postconfig.xml
+++ b/oidfed-common-conf-impl/src/main/resources/META-INF/net.shibboleth.idp/postconfig.xml
@@ -602,19 +602,23 @@
</bean>
</property>
<property name="criteriaSetLookupStrategy">
- <bean class="net.shibboleth.oidfed.metadata.cache.trustmark.DefaultTrustMarkValidationCriteriaSetLookupFunction"
- p:trustChainCache-ref="shibboleth.oidfed.TrustChainMetadataCache"
- p:entityConfigurationCache-ref="shibboleth.oidfed.EntityConfigurationMetadataCache"
- p:localTrustAnchorsCache-ref="shibboleth.oidfed.LocalTrustAnchorsMetadataCache">
- <property name="trustEngine">
- <bean class="net.shibboleth.oidc.security.impl.ExplicitKeySignedJWTTrustEngine">
- <constructor-arg index="0">
- <bean class="net.shibboleth.oidfed.security.credential.DefaultLocalTrustAnchorCredentialResolver"
- c:cache-ref="shibboleth.oidfed.LocalTrustAnchorsMetadataCache" />
- </constructor-arg>
- <constructor-arg index="1">
- <bean class="net.shibboleth.oidfed.security.credential.DefaultPayloadJOSEObjectCredentialResolver" />
- </constructor-arg>
+ <bean class="net.shibboleth.oidfed.metadata.cache.trustmark.DefaultTrustMarkValidationCriteriaSetLookupFunction">
+ <property name="trustMarkIssuerConfigurationFetchingStrategy">
+ <bean class="net.shibboleth.oidfed.metadata.cache.trustmark.DefaultTrustMarkIssuerConfigurationFetchingStrategy"
+ p:trustChainCache-ref="shibboleth.oidfed.TrustChainMetadataCache"
+ p:entityConfigurationCache-ref="shibboleth.oidfed.EntityConfigurationMetadataCache"
+ p:localTrustAnchorsCache-ref="shibboleth.oidfed.LocalTrustAnchorsMetadataCache">
+ <property name="trustEngine">
+ <bean class="net.shibboleth.oidc.security.impl.ExplicitKeySignedJWTTrustEngine">
+ <constructor-arg index="0">
+ <bean class="net.shibboleth.oidfed.security.credential.DefaultLocalTrustAnchorCredentialResolver"
+ c:cache-ref="shibboleth.oidfed.LocalTrustAnchorsMetadataCache" />
+ </constructor-arg>
+ <constructor-arg index="1">
+ <bean class="net.shibboleth.oidfed.security.credential.DefaultPayloadJOSEObjectCredentialResolver" />
+ </constructor-arg>
+ </bean>
+ </property>
</bean>
</property>
</bean>
@@ -718,19 +722,23 @@
<bean class="net.shibboleth.oidfed.metadata.cache.DefaultEntityStatementSignatureValidationCondition"
p:trustEngine-ref="shibboleth.oidfed.DefaultSubordinateStatementTrustEngine">
<property name="criteriaSetLookupStrategy">
- <bean class="net.shibboleth.oidfed.metadata.cache.trustmark.DefaultTrustMarkValidationCriteriaSetLookupFunction"
- p:trustChainCache-ref="shibboleth.oidfed.TrustChainMetadataCache"
- p:entityConfigurationCache-ref="shibboleth.oidfed.EntityConfigurationMetadataCache"
- p:localTrustAnchorsCache-ref="shibboleth.oidfed.LocalTrustAnchorsMetadataCache">
- <property name="trustEngine">
- <bean class="net.shibboleth.oidc.security.impl.ExplicitKeySignedJWTTrustEngine">
- <constructor-arg index="0">
- <bean class="net.shibboleth.oidfed.security.credential.DefaultLocalTrustAnchorCredentialResolver"
- c:cache-ref="shibboleth.oidfed.LocalTrustAnchorsMetadataCache" />
- </constructor-arg>
- <constructor-arg index="1">
- <bean class="net.shibboleth.oidfed.security.credential.DefaultPayloadJOSEObjectCredentialResolver" />
- </constructor-arg>
+ <bean class="net.shibboleth.oidfed.metadata.cache.trustmark.DefaultTrustMarkValidationCriteriaSetLookupFunction">
+ <property name="trustMarkIssuerConfigurationFetchingStrategy">
+ <bean class="net.shibboleth.oidfed.metadata.cache.trustmark.DefaultTrustMarkIssuerConfigurationFetchingStrategy"
+ p:trustChainCache-ref="shibboleth.oidfed.TrustChainMetadataCache"
+ p:entityConfigurationCache-ref="shibboleth.oidfed.EntityConfigurationMetadataCache"
+ p:localTrustAnchorsCache-ref="shibboleth.oidfed.LocalTrustAnchorsMetadataCache">
+ <property name="trustEngine">
+ <bean class="net.shibboleth.oidc.security.impl.ExplicitKeySignedJWTTrustEngine">
+ <constructor-arg index="0">
+ <bean class="net.shibboleth.oidfed.security.credential.DefaultLocalTrustAnchorCredentialResolver"
+ c:cache-ref="shibboleth.oidfed.LocalTrustAnchorsMetadataCache" />
+ </constructor-arg>
+ <constructor-arg index="1">
+ <bean class="net.shibboleth.oidfed.security.credential.DefaultPayloadJOSEObjectCredentialResolver" />
+ </constructor-arg>
+ </bean>
+ </property>
</bean>
</property>
</bean>
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 18ce67e..c2f0bc5 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
@@ -55,7 +55,7 @@
<bean id="ResolveTrustMarks" class="net.shibboleth.oidfed.profile.impl.ResolveTrustMarks"
scope="prototype"
- p:trustChainCache-ref="#{'%{idp.oidfed.admin.resolvertest.TrustChainMetadataCache:shibboleth.oidfed.TrustChainMetadataCache}'.trim()}"
+ p:trustedTrustMarkIssuersOnlyCondition-ref="#{'%{idp.oidfed.admin.resolvertest.TrustedTrustMarkIssuersOnlyCondition:shibboleth.Conditions.TRUE}'.trim()}"
p:trustMarkClaimsValidationLookupStrategy="#{getObject('shibboleth.oidfed.TrustMarkClaimsValidationLookupStrategy') ?: getObject('DefaultTrustMarkClaimsValidationLookupStrategy')}"
p:delegatedTrustMarkClaimsValidationLookupStrategy="#{getObject('shibboleth.oidfed.DelegatedTrustMarkClaimsValidationLookupStrategy') ?: getObject('DefaultDelegatedTrustMarkClaimsValidationLookupStrategy')}"
p:trustEngine-ref="shibboleth.oidfed.DefaultEntityConfigurationTrustEngine"
@@ -70,6 +70,24 @@
<property name="trustedTrustMarkOwnersLookupStrategy">
<bean class="net.shibboleth.oidfed.profile.navigate.DefaultTrustChainTrustedTrustMarkOwnersLookupStrategy"/>
</property>
+ <property name="trustMarkIssuerConfigurationFetchingStrategy">
+ <bean class="net.shibboleth.oidfed.metadata.cache.trustmark.DefaultTrustMarkIssuerConfigurationFetchingStrategy"
+ p:trustChainCache-ref="#{'%{idp.oidfed.admin.resolvertest.TrustChainMetadataCache:shibboleth.oidfed.TrustChainMetadataCache}'.trim()}"
+ p:entityConfigurationCache-ref="#{'%{idp.oidfed.admin.resolvertest.EntityConfigurationMetadataCache:shibboleth.oidfed.EntityConfigurationMetadataCache}'.trim()}"
+ p:localTrustAnchorsCache-ref="#{'%{idp.oidfed.admin.resolvertest.LocalTrustAnchorsMetadataCache:shibboleth.oidfed.LocalTrustAnchorsMetadataCache}'.trim()}">
+ <property name="trustEngine">
+ <bean class="net.shibboleth.oidc.security.impl.ExplicitKeySignedJWTTrustEngine">
+ <constructor-arg index="0">
+ <bean class="net.shibboleth.oidfed.security.credential.DefaultLocalTrustAnchorCredentialResolver"
+ c:cache-ref="#{'%{idp.oidfed.admin.resolvertest.LocalTrustAnchorsMetadataCache:shibboleth.oidfed.LocalTrustAnchorsMetadataCache}'.trim()}" />
+ </constructor-arg>
+ <constructor-arg index="1">
+ <bean class="net.shibboleth.oidfed.security.credential.DefaultPayloadJOSEObjectCredentialResolver" />
+ </constructor-arg>
+ </bean>
+ </property>
+ </bean>
+ </property>
</bean>
<bean id="ValidateTrustMarks" class="net.shibboleth.oidfed.profile.impl.ValidateTrustMarks"
diff --git a/oidfed-common-conf-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidfed/resolve-entity/resolve-entity-beans.xml b/oidfed-common-conf-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidfed/resolve-entity/resolve-entity-beans.xml
index 5c34d90..8ed1b1a 100644
--- a/oidfed-common-conf-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidfed/resolve-entity/resolve-entity-beans.xml
+++ b/oidfed-common-conf-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidfed/resolve-entity/resolve-entity-beans.xml
@@ -174,7 +174,7 @@
<bean id="ResolveTrustMarks" class="net.shibboleth.oidfed.profile.impl.ResolveTrustMarks"
scope="prototype"
- p:trustChainCache-ref="#{'%{idp.oidfed.resolveEntity.TrustChainMetadataCache:shibboleth.oidfed.TrustChainMetadataCache}'.trim()}"
+ p:trustedTrustMarkIssuersOnlyCondition-ref="#{'%{idp.oidfed.resolveEntity.TrustedTrustMarkIssuersOnlyCondition:shibboleth.Conditions.TRUE}'.trim()}"
p:trustMarkClaimsValidationLookupStrategy="#{getObject('shibboleth.oidfed.TrustMarkClaimsValidationLookupStrategy') ?: getObject('DefaultTrustMarkClaimsValidationLookupStrategy')}"
p:delegatedTrustMarkClaimsValidationLookupStrategy="#{getObject('shibboleth.oidfed.DelegatedTrustMarkClaimsValidationLookupStrategy') ?: getObject('DefaultDelegatedTrustMarkClaimsValidationLookupStrategy')}"
p:trustEngine-ref="shibboleth.oidfed.DefaultEntityConfigurationTrustEngine"
@@ -189,6 +189,24 @@
<property name="trustedTrustMarkOwnersLookupStrategy">
<bean class="net.shibboleth.oidfed.profile.navigate.DefaultTrustChainTrustedTrustMarkOwnersLookupStrategy"/>
</property>
+ <property name="trustMarkIssuerConfigurationFetchingStrategy">
+ <bean class="net.shibboleth.oidfed.metadata.cache.trustmark.DefaultTrustMarkIssuerConfigurationFetchingStrategy"
+ p:trustChainCache-ref="#{'%{idp.oidfed.resolveEntity.TrustChainMetadataCache:shibboleth.oidfed.TrustChainMetadataCache}'.trim()}"
+ p:entityConfigurationCache-ref="#{'%{idp.oidfed.resolveEntity.EntityConfigurationMetadataCache:shibboleth.oidfed.EntityConfigurationMetadataCache}'.trim()}"
+ p:localTrustAnchorsCache-ref="#{'%{idp.oidfed.resolveEntity.LocalTrustAnchorsMetadataCache:shibboleth.oidfed.LocalTrustAnchorsMetadataCache}'.trim()}">
+ <property name="trustEngine">
+ <bean class="net.shibboleth.oidc.security.impl.ExplicitKeySignedJWTTrustEngine">
+ <constructor-arg index="0">
+ <bean class="net.shibboleth.oidfed.security.credential.DefaultLocalTrustAnchorCredentialResolver"
+ c:cache-ref="#{'%{idp.oidfed.resolveEntity.LocalTrustAnchorsMetadataCache:shibboleth.oidfed.LocalTrustAnchorsMetadataCache}'.trim()}" />
+ </constructor-arg>
+ <constructor-arg index="1">
+ <bean class="net.shibboleth.oidfed.security.credential.DefaultPayloadJOSEObjectCredentialResolver" />
+ </constructor-arg>
+ </bean>
+ </property>
+ </bean>
+ </property>
</bean>
<bean id="ValidateTrustMarks" class="net.shibboleth.oidfed.profile.impl.ValidateTrustMarks"
diff --git a/oidfed-common-impl/src/main/java/net/shibboleth/oidfed/metadata/cache/trustmark/DefaultTrustMarkValidationCriteriaSetLookupFunction.java b/oidfed-common-impl/src/main/java/net/shibboleth/oidfed/metadata/cache/trustmark/DefaultTrustMarkIssuerConfigurationFetchingStrategy.java
similarity index 71%
copy from oidfed-common-impl/src/main/java/net/shibboleth/oidfed/metadata/cache/trustmark/DefaultTrustMarkValidationCriteriaSetLookupFunction.java
copy to oidfed-common-impl/src/main/java/net/shibboleth/oidfed/metadata/cache/trustmark/DefaultTrustMarkIssuerConfigurationFetchingStrategy.java
index 1058e04..6ba1fbd 100644
--- a/oidfed-common-impl/src/main/java/net/shibboleth/oidfed/metadata/cache/trustmark/DefaultTrustMarkValidationCriteriaSetLookupFunction.java
+++ b/oidfed-common-impl/src/main/java/net/shibboleth/oidfed/metadata/cache/trustmark/DefaultTrustMarkIssuerConfigurationFetchingStrategy.java
@@ -29,11 +29,8 @@ import net.shibboleth.oidfed.metadata.BaseJWTWrapper;
import net.shibboleth.oidfed.metadata.EntityConfiguration;
import net.shibboleth.oidfed.metadata.EntityStatement;
import net.shibboleth.oidfed.metadata.cache.AbstractTrustEngineSignatureValidationComponent;
-import net.shibboleth.oidfed.metadata.cache.BaseExpirableStatementContainer;
-import net.shibboleth.oidfed.metadata.cache.IssuerEntityStatementCriterion;
import net.shibboleth.oidfed.metadata.cache.SubjectEntityIDCriterion;
import net.shibboleth.oidfed.metadata.cache.SubjectEntityStatementCriterion;
-import net.shibboleth.oidfed.metadata.cache.SubjectStatementCriterion;
import net.shibboleth.oidfed.metadata.cache.configuration.EntityConfigurationContainer;
import net.shibboleth.oidfed.metadata.cache.local.LocalKeyContainer;
import net.shibboleth.oidfed.metadata.cache.trustchain.TrustChainsContainer;
@@ -45,23 +42,23 @@ import net.shibboleth.shared.primitive.LoggerFactory;
import net.shibboleth.shared.resolver.CriteriaSet;
/**
- * Default criteria set lookup strategy for {@link BaseExpirableStatementContainer} that fetches the issuer
- * entity statement via trust chain cache or via entity configuration cache if the entity is locally trusted. In that
- * case the entity configuration is verified against the local trust anchor cache.
+ * Default fetching strategy for trust marks that fetches the issuer entity configuration via trust chain cache or via
+ * entity configuration cache if the entity is locally trusted. In that case the entity configuration is verified
+ * against the local trust anchor cache using the configurable trust engine.
*/
@ThreadSafeAfterInit
-public class DefaultTrustMarkValidationCriteriaSetLookupFunction
+public class DefaultTrustMarkIssuerConfigurationFetchingStrategy
extends AbstractTrustEngineSignatureValidationComponent
- implements Function<BaseExpirableStatementContainer<?>, CriteriaSet> {
+ implements Function<BaseJWTWrapper<?>, EntityConfiguration> {
/** Class logger. */
@Nonnull
- private Logger log = LoggerFactory.getLogger(DefaultTrustMarkValidationCriteriaSetLookupFunction.class);
+ private Logger log = LoggerFactory.getLogger(DefaultTrustMarkIssuerConfigurationFetchingStrategy.class);
/** Cache used to fetch the issuer entity configuration of entities that are not locally trusted. */
@NonnullAfterInit private MetadataCache<TrustChainsContainer> trustChainCache;
- /** Cache used to fetch the isser entity configuration of locally trusted entities. */
+ /** Cache used to fetch the issuer entity configuration of locally trusted entities. */
@NonnullAfterInit private MetadataCache<EntityConfigurationContainer> entityConfigurationCache;
/** Cache containing local copies of trusted trust anchor keys. */
@@ -78,9 +75,9 @@ public class DefaultTrustMarkValidationCriteriaSetLookupFunction
}
/**
- * Set the cache used to fetch the isser entity configuration of locally trusted entities.
+ * Set the cache used to fetch the issuer entity configuration of locally trusted entities.
*
- * @param cache cache used to fetch the isser entity configuration of locally trusted entities
+ * @param cache cache used to fetch the issuer entity configuration of locally trusted entities
*/
public void setEntityConfigurationCache(@Nonnull final MetadataCache<EntityConfigurationContainer> cache) {
checkSetterPreconditions();
@@ -114,33 +111,13 @@ public class DefaultTrustMarkValidationCriteriaSetLookupFunction
/** {@inheritDoc} */
@Override @Nullable
- public CriteriaSet apply(@Nullable final BaseExpirableStatementContainer<?> metadataContainer) {
- if (metadataContainer != null && metadataContainer.getStatement() != null) {
- final BaseJWTWrapper<?> statement = metadataContainer.getStatement();
- assert statement != null;
- final SubjectStatementCriterion subjectCriterion = new SubjectStatementCriterion(statement);
- final IssuerEntityStatementCriterion issuerCriterion = getIssuerCriterion(statement, metadataContainer);
- if (issuerCriterion == null) {
- log.debug("Issuer statement could not be fetched, returning null");
- return null;
- }
- return new CriteriaSet(subjectCriterion, issuerCriterion);
+ public EntityConfiguration apply(@Nullable final BaseJWTWrapper<?> wrapper) {
+ checkComponentActive();
+ if (wrapper == null) {
+ return null;
}
- log.debug("Entity statement is not found from the container, returning null");
- return null;
- }
- /**
- * Fetch the issuer entity configuration from the metadata cache and initialize the criterion.
- *
- * @param statement the entity statement whose issuer is fetched
- * @param metadataContainer the metadata container containing the statement
- * @return the issuer entity configuration, or null if could not be fetched
- */
- @Nullable protected IssuerEntityStatementCriterion getIssuerCriterion(
- @Nonnull final BaseJWTWrapper<?> statement,
- @Nonnull final BaseExpirableStatementContainer<?> metadataContainer) {
- final String issuer = statement.getIssuer();
+ final String issuer = wrapper.getIssuer();
final CriteriaSet criteria = new CriteriaSet(new SubjectEntityIDCriterion(issuer));
if (isLocallyTrusted(issuer)) {
try {
@@ -150,8 +127,8 @@ public class DefaultTrustMarkValidationCriteriaSetLookupFunction
if (issuerStatement != null) {
final var anchorCriteria = new CriteriaSet(
new SubjectEntityStatementCriterion(issuerStatement));
- if (validateJwt(statement.getJwt(), anchorCriteria, metadataContainer.getEntityId())) {
- return new IssuerEntityStatementCriterion(issuerStatement);
+ if (validateJwt(wrapper.getJwt(), anchorCriteria, issuer)) {
+ return issuerStatement;
}
log.warn("Could not validate the issuer entity configuration against trust engine");
return null;
@@ -168,8 +145,9 @@ public class DefaultTrustMarkValidationCriteriaSetLookupFunction
final List<List<EntityStatement<?>>> chains = result.get(0).getTrustChains();
if (!chains.isEmpty()) {
final EntityStatement<?> issuerStatement = chains.get(0).get(0);
- assert issuerStatement != null;
- return new IssuerEntityStatementCriterion(issuerStatement);
+ if (issuerStatement instanceof EntityConfiguration configuration) {
+ return configuration;
+ }
}
}
} catch (final MetadataCacheException e) {
diff --git a/oidfed-common-impl/src/main/java/net/shibboleth/oidfed/metadata/cache/trustmark/DefaultTrustMarkValidationCriteriaSetLookupFunction.java b/oidfed-common-impl/src/main/java/net/shibboleth/oidfed/metadata/cache/trustmark/DefaultTrustMarkValidationCriteriaSetLookupFunction.java
index 1058e04..7c19094 100644
--- a/oidfed-common-impl/src/main/java/net/shibboleth/oidfed/metadata/cache/trustmark/DefaultTrustMarkValidationCriteriaSetLookupFunction.java
+++ b/oidfed-common-impl/src/main/java/net/shibboleth/oidfed/metadata/cache/trustmark/DefaultTrustMarkValidationCriteriaSetLookupFunction.java
@@ -14,8 +14,6 @@
package net.shibboleth.oidfed.metadata.cache.trustmark;
-import java.util.List;
-import java.util.Map;
import java.util.function.Function;
import javax.annotation.Nonnull;
@@ -23,22 +21,14 @@ import javax.annotation.Nullable;
import org.slf4j.Logger;
-import net.shibboleth.oidc.metadata.cache.MetadataCache;
-import net.shibboleth.oidc.metadata.cache.MetadataCacheException;
import net.shibboleth.oidfed.metadata.BaseJWTWrapper;
import net.shibboleth.oidfed.metadata.EntityConfiguration;
-import net.shibboleth.oidfed.metadata.EntityStatement;
-import net.shibboleth.oidfed.metadata.cache.AbstractTrustEngineSignatureValidationComponent;
import net.shibboleth.oidfed.metadata.cache.BaseExpirableStatementContainer;
import net.shibboleth.oidfed.metadata.cache.IssuerEntityStatementCriterion;
-import net.shibboleth.oidfed.metadata.cache.SubjectEntityIDCriterion;
-import net.shibboleth.oidfed.metadata.cache.SubjectEntityStatementCriterion;
import net.shibboleth.oidfed.metadata.cache.SubjectStatementCriterion;
-import net.shibboleth.oidfed.metadata.cache.configuration.EntityConfigurationContainer;
-import net.shibboleth.oidfed.metadata.cache.local.LocalKeyContainer;
-import net.shibboleth.oidfed.metadata.cache.trustchain.TrustChainsContainer;
import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
import net.shibboleth.shared.annotation.constraint.ThreadSafeAfterInit;
+import net.shibboleth.shared.component.AbstractIdentifiableInitializableComponent;
import net.shibboleth.shared.component.ComponentInitializationException;
import net.shibboleth.shared.logic.Constraint;
import net.shibboleth.shared.primitive.LoggerFactory;
@@ -46,69 +36,41 @@ import net.shibboleth.shared.resolver.CriteriaSet;
/**
* Default criteria set lookup strategy for {@link BaseExpirableStatementContainer} that fetches the issuer
- * entity statement via trust chain cache or via entity configuration cache if the entity is locally trusted. In that
- * case the entity configuration is verified against the local trust anchor cache.
+ * entity configuration via configurable fetching strategy.
*/
@ThreadSafeAfterInit
public class DefaultTrustMarkValidationCriteriaSetLookupFunction
- extends AbstractTrustEngineSignatureValidationComponent
+ extends AbstractIdentifiableInitializableComponent
implements Function<BaseExpirableStatementContainer<?>, CriteriaSet> {
/** Class logger. */
@Nonnull
private Logger log = LoggerFactory.getLogger(DefaultTrustMarkValidationCriteriaSetLookupFunction.class);
- /** Cache used to fetch the issuer entity configuration of entities that are not locally trusted. */
- @NonnullAfterInit private MetadataCache<TrustChainsContainer> trustChainCache;
-
- /** Cache used to fetch the isser entity configuration of locally trusted entities. */
- @NonnullAfterInit private MetadataCache<EntityConfigurationContainer> entityConfigurationCache;
-
- /** Cache containing local copies of trusted trust anchor keys. */
- @NonnullAfterInit private MetadataCache<Map<String, LocalKeyContainer>> localTrustAnchorsCache;
-
- /**
- * Set the cache used to fetch the issuer entity configuration of entities that are not locally trusted.
- *
- * @param cache cache used to fetch the issuer entity configuration of entities that are not locally trusted
- */
- public void setTrustChainCache(@Nonnull final MetadataCache<TrustChainsContainer> cache) {
- checkSetterPreconditions();
- trustChainCache = Constraint.isNotNull(cache, "Trust Chain cache cannot be null");
- }
-
- /**
- * Set the cache used to fetch the isser entity configuration of locally trusted entities.
- *
- * @param cache cache used to fetch the isser entity configuration of locally trusted entities
- */
- public void setEntityConfigurationCache(@Nonnull final MetadataCache<EntityConfigurationContainer> cache) {
- checkSetterPreconditions();
- entityConfigurationCache = Constraint.isNotNull(cache, "Entity Configuration cache cannot be null");
- }
+ /** Strategy used to fetch trust mark issuer entity configuration. */
+ @NonnullAfterInit
+ private Function<BaseJWTWrapper<?>, EntityConfiguration> trustMarkIssuerConfigurationFetchingStrategy;
/**
- * Set the cache containing local copies of trusted trust anchor keys.
+ * Set the strategy used to fetch the trust mark issuer entity configuration
*
- * @param cache cache containing local copies of trusted trust anchor keys.
+ * @param strategy fetching strategy
*/
- public void setLocalTrustAnchorsCache(@Nonnull final MetadataCache<Map<String, LocalKeyContainer>> cache) {
+ public void setTrustMarkIssuerConfigurationFetchingStrategy(
+ @Nonnull final Function<BaseJWTWrapper<?>, EntityConfiguration> strategy) {
checkSetterPreconditions();
- localTrustAnchorsCache = Constraint.isNotNull(cache, "Local Trust Anchor cache cannot be null");
+ trustMarkIssuerConfigurationFetchingStrategy = Constraint.isNotNull(strategy,
+ "TrustMarkIssuerConfigurationFetchingStrategy cannot be null");
}
/** {@inheritDoc} */
@Override
protected void doInitialize() throws ComponentInitializationException {
super.doInitialize();
- if (trustChainCache == null) {
- throw new ComponentInitializationException("Trust Chain cache cannot be null");
- }
- if (entityConfigurationCache == null) {
- throw new ComponentInitializationException("Entity configuration cache cannot be null");
- }
- if (localTrustAnchorsCache == null) {
- throw new ComponentInitializationException("Local Trust Anchor cache cannot be null");
+
+ if (trustMarkIssuerConfigurationFetchingStrategy == null) {
+ throw new ComponentInitializationException(
+ "TrustMarkIssuerConfigurationFetchingStrategy cannot be null");
}
}
@@ -119,88 +81,16 @@ public class DefaultTrustMarkValidationCriteriaSetLookupFunction
final BaseJWTWrapper<?> statement = metadataContainer.getStatement();
assert statement != null;
final SubjectStatementCriterion subjectCriterion = new SubjectStatementCriterion(statement);
- final IssuerEntityStatementCriterion issuerCriterion = getIssuerCriterion(statement, metadataContainer);
- if (issuerCriterion == null) {
+
+ final EntityConfiguration issuerConfiguration =
+ trustMarkIssuerConfigurationFetchingStrategy.apply(statement);
+ if (issuerConfiguration == null) {
log.debug("Issuer statement could not be fetched, returning null");
return null;
}
- return new CriteriaSet(subjectCriterion, issuerCriterion);
+ return new CriteriaSet(subjectCriterion, new IssuerEntityStatementCriterion(issuerConfiguration));
}
log.debug("Entity statement is not found from the container, returning null");
return null;
}
-
- /**
- * Fetch the issuer entity configuration from the metadata cache and initialize the criterion.
- *
- * @param statement the entity statement whose issuer is fetched
- * @param metadataContainer the metadata container containing the statement
- * @return the issuer entity configuration, or null if could not be fetched
- */
- @Nullable protected IssuerEntityStatementCriterion getIssuerCriterion(
- @Nonnull final BaseJWTWrapper<?> statement,
- @Nonnull final BaseExpirableStatementContainer<?> metadataContainer) {
- final String issuer = statement.getIssuer();
- final CriteriaSet criteria = new CriteriaSet(new SubjectEntityIDCriterion(issuer));
- if (isLocallyTrusted(issuer)) {
- try {
- final List<EntityConfigurationContainer> result = entityConfigurationCache.get(criteria);
- if (!result.isEmpty()) {
- final EntityConfiguration issuerStatement = result.get(0).getStatement();
- if (issuerStatement != null) {
- final var anchorCriteria = new CriteriaSet(
- new SubjectEntityStatementCriterion(issuerStatement));
- if (validateJwt(statement.getJwt(), anchorCriteria, metadataContainer.getEntityId())) {
- return new IssuerEntityStatementCriterion(issuerStatement);
- }
- log.warn("Could not validate the issuer entity configuration against trust engine");
- return null;
- }
- }
- } catch (final MetadataCacheException e) {
- log.debug("Error while fetching issuer entity configuration for {}", issuer, e);
- }
- log.warn("Could not fetch entity configuration via entity configuration cache for {}", issuer);
- }
- try {
- final List<TrustChainsContainer> result = trustChainCache.get(criteria);
- if (!result.isEmpty()) {
- final List<List<EntityStatement<?>>> chains = result.get(0).getTrustChains();
- if (!chains.isEmpty()) {
- final EntityStatement<?> issuerStatement = chains.get(0).get(0);
- assert issuerStatement != null;
- return new IssuerEntityStatementCriterion(issuerStatement);
- }
- }
- } catch (final MetadataCacheException e) {
- log.debug("Error while fetching issuer trust chain for {}", issuer, e);
- }
- log.warn("Could not fetch entity configuration via trust chain cache for {}", issuer);
- return null;
-
- }
-
- /**
- * Checks whether the given entity is locally trusted via local trust anchors cache.
- *
- * @param entity entity ID to be verified
- * @return true if the entity is locally trusted, false otherwise
- */
- private boolean isLocallyTrusted(@Nonnull final String entity) {
- final CriteriaSet criteria = new CriteriaSet(new SubjectEntityIDCriterion(entity));
- final List<Map<String, LocalKeyContainer>> keyContainers;
- try {
- keyContainers = localTrustAnchorsCache.get(criteria);
- } catch (final MetadataCacheException e) {
- log.debug("Could not resolve local trust anchor keys from the cache for {}", entity, e);
- return false;
- }
- if (keyContainers.isEmpty() || !keyContainers.get(0).containsKey(entity)) {
- log.trace("No locally trusted keys found for {}", entity);
- return false;
- }
- log.trace("Locally trusted keys configured for {}", entity);
- return true;
- }
-
}
diff --git a/oidfed-common-impl/src/main/java/net/shibboleth/oidfed/profile/impl/ResolveTrustMarks.java b/oidfed-common-impl/src/main/java/net/shibboleth/oidfed/profile/impl/ResolveTrustMarks.java
index f082794..9c5e38d 100644
--- a/oidfed-common-impl/src/main/java/net/shibboleth/oidfed/profile/impl/ResolveTrustMarks.java
+++ b/oidfed-common-impl/src/main/java/net/shibboleth/oidfed/profile/impl/ResolveTrustMarks.java
@@ -42,14 +42,13 @@ import com.nimbusds.jwt.SignedJWT;
import net.shibboleth.idp.profile.AbstractProfileAction;
import net.shibboleth.oidc.jwt.claims.ClaimsValidator;
import net.shibboleth.oidc.jwt.claims.JWTValidationException;
-import net.shibboleth.oidc.metadata.cache.MetadataCache;
-import net.shibboleth.oidc.metadata.cache.MetadataCacheException;
+import net.shibboleth.oidfed.metadata.BaseJWTWrapper;
+import net.shibboleth.oidfed.metadata.EntityConfiguration;
import net.shibboleth.oidfed.metadata.EntityStatement;
import net.shibboleth.oidfed.metadata.TrustMark;
import net.shibboleth.oidfed.metadata.cache.SubjectEntityIDCriterion;
import net.shibboleth.oidfed.metadata.cache.SubjectEntityStatementCriterion;
import net.shibboleth.oidfed.metadata.cache.TrustMarkOwnersCriterion;
-import net.shibboleth.oidfed.metadata.cache.trustchain.TrustChainsContainer;
import net.shibboleth.oidfed.metadata.payload.TrustMarkPayload;
import net.shibboleth.oidfed.metadata.payload.claim.TrustMarkOwner;
import net.shibboleth.oidfed.profile.context.RelyingPartyTrustChainContext;
@@ -80,6 +79,10 @@ public class ResolveTrustMarks extends AbstractProfileAction {
/** Strategy used to lookup the trust chain context. */
@Nonnull private Function<ProfileRequestContext, RelyingPartyTrustChainContext> trustChainContextLookupStrategy;
+ /** Strategy used to fetch trust mark issuer entity configuration. */
+ @NonnullAfterInit
+ private Function<BaseJWTWrapper<?>, EntityConfiguration> trustMarkIssuerConfigurationFetchingStrategy;
+
/** Strategy used to parse trust marks from the selected trust chain. */
@NonnullAfterInit
private Function<List<EntityStatement<?>>,Map<String,List<TrustMark>>> trustChainTrustMarksParsingStrategy;
@@ -95,9 +98,6 @@ public class ResolveTrustMarks extends AbstractProfileAction {
/** Condition to solely take trusted trust mark issuers into account. */
@Nonnull private Predicate<ProfileRequestContext> trustedTrustMarkIssuersOnlyCondition;
- /** Metadata cache for trust chains (for trust mark issuers). */
- @NonnullAfterInit private MetadataCache<TrustChainsContainer> trustChainCache;
-
/** Trust engine used to validate a trust mark signature. */
@NonnullAfterInit private TrustEngine<SignedJWT> trustEngine;
@@ -195,13 +195,15 @@ public class ResolveTrustMarks extends AbstractProfileAction {
}
/**
- * Set the metadata cache for trust chains.
+ * Set the strategy used to fetch the trust mark issuer entity configuration
*
- * @param cache metadata cache
+ * @param strategy fetching strategy
*/
- public void setTrustChainCache(@Nonnull final MetadataCache<TrustChainsContainer> cache) {
+ public void setTrustMarkIssuerConfigurationFetchingStrategy(
+ @Nonnull final Function<BaseJWTWrapper<?>, EntityConfiguration> strategy) {
checkSetterPreconditions();
- trustChainCache = Constraint.isNotNull(cache, "TrustChainCache cannot be null");
+ trustMarkIssuerConfigurationFetchingStrategy = Constraint.isNotNull(strategy,
+ "TrustMarkIssuerConfigurationFetchingStrategy cannot be null");
}
/**
@@ -253,8 +255,9 @@ public class ResolveTrustMarks extends AbstractProfileAction {
protected void doInitialize() throws ComponentInitializationException {
super.doInitialize();
- if (trustChainCache == null) {
- throw new ComponentInitializationException("TrustChainCache cannot be null");
+ if (trustMarkIssuerConfigurationFetchingStrategy == null) {
+ throw new ComponentInitializationException(
+ "TrustMarkIssuerConfigurationFetchingStrategy cannot be null");
}
if (trustEngine == null) {
throw new ComponentInitializationException("Trust Engine cannot be null");
@@ -366,8 +369,7 @@ public class ResolveTrustMarks extends AbstractProfileAction {
verifiedTrustMarks.put(
statement.getSubject(),
trustMarks.stream()
- .filter(entry -> onlyTrustedIssuers ?
- checkTrustedIssuer(entry, trustedIssuers, trustedOwners) : true)
+ .filter(entry -> checkTrustedIssuer(entry, trustedIssuers, trustedOwners, onlyTrustedIssuers))
.filter(entry -> verifyTrustMark(entry, trustedOwners, profileRequestContext,
trustChainContext.getVerifiedTrustMarkIssuers()))
.filter(Objects::nonNull)
@@ -412,11 +414,12 @@ public class ResolveTrustMarks extends AbstractProfileAction {
* @param trustMark the trust mark to be verified
* @param trustedIssuers the trusted trust mark issuers
* @param trustedOwners the trusted trust mark owners
+ * @param onlyTrustedIssuers if only trusted issuers should be taken into account
* @return true if the trust mark meets configuration, false otherwise
*/
protected boolean checkTrustedIssuer(@Nullable final TrustMark trustMark,
@Nonnull final Map<String, List<String>> trustedIssuers,
- @Nonnull final Map<String, TrustMarkOwner> trustedOwners) {
+ @Nonnull final Map<String, TrustMarkOwner> trustedOwners, final boolean onlyTrustedIssuers) {
if (trustMark == null) {
return false;
}
@@ -427,19 +430,20 @@ public class ResolveTrustMarks extends AbstractProfileAction {
if (trustedIssuers.containsKey(id)) {
final String issuer = trustMark.getIssuer();
final List<String> validIssuers = trustedIssuers.get(id);
- if (validIssuers == null || !validIssuers.contains(issuer)) {
+ if (validIssuers == null || (!validIssuers.isEmpty() && !validIssuers.contains(issuer))) {
log.debug("{} Issuer {} is not valid trust mark issuer", getLogPrefix(), issuer);
return false;
}
} else if (trustedOwners.containsKey(id)) {
log.debug("{} Trust mark ID {} is included in trusted owners", getLogPrefix(), id);
if (trustMark.getParsedPayload().getDelegation() == null) {
- log.debug("(} Trust mark ID {} does not contain a delegation claim", getLogPrefix(), id);
+ log.debug("{} Trust mark ID {} does not contain a delegation claim", getLogPrefix(), id);
return false;
}
} else {
- log.debug("{} Trust mark ID {} is not included in the trusted issuers", getLogPrefix(), id);
- return false;
+ log.debug("{} Trust mark ID {} is not included in the trusted issuers, accepting {}", getLogPrefix(), id,
+ !onlyTrustedIssuers);
+ return !onlyTrustedIssuers;
}
return true;
}
@@ -463,21 +467,10 @@ public class ResolveTrustMarks extends AbstractProfileAction {
}
final String issuer = trustMark.getIssuer();
assert issuer != null;
- log.debug("{} Resolving trust chain for {}", getLogPrefix(), issuer);
- final List<TrustChainsContainer> cacheResult;
- try {
- cacheResult = trustChainCache.get(new CriteriaSet(new SubjectEntityIDCriterion(issuer)));
- } catch (final MetadataCacheException e) {
- log.warn("{} Exception while fetching trust chains for {}", getLogPrefix(), issuer, e);
- return false;
- }
- if (cacheResult.isEmpty() || cacheResult.get(0).getTrustChains().isEmpty()) {
- log.warn("{} No trust chains resolved for {}", getLogPrefix(), issuer);
+ final EntityStatement<?> trustMarkIssuer = trustMarkIssuerConfigurationFetchingStrategy.apply(trustMark);
+ if (trustMarkIssuer == null) {
return false;
}
- final List<EntityStatement<?>> trustMarkChain = cacheResult.get(0).getTrustChains().get(0);
- final EntityStatement<?> trustMarkIssuer = trustMarkChain.get(0);
- assert trustMarkIssuer != null;
final CriteriaSet criteria = new CriteriaSet(new SubjectEntityStatementCriterion(trustMarkIssuer));
trustedTrustMarkIssuers.put(trustMarkIssuer.getSubject(), trustMarkIssuer);
log.trace("{} Validating entity statement {}", getLogPrefix(), trustMarkIssuer.getJwt().serialize());
diff --git a/oidfed-common-impl/src/main/resources/net/shibboleth/oidfed/conf/oidfed/oidfed.properties b/oidfed-common-impl/src/main/resources/net/shibboleth/oidfed/conf/oidfed/oidfed.properties
index c2e1c91..e5d1fec 100644
--- a/oidfed-common-impl/src/main/resources/net/shibboleth/oidfed/conf/oidfed/oidfed.properties
+++ b/oidfed-common-impl/src/main/resources/net/shibboleth/oidfed/conf/oidfed/oidfed.properties
@@ -129,7 +129,10 @@ idp.oidfed.entityConfiguration.authorityHints = https://your.authority.example.o
#idp.oidfed.admin.resolvertest.postAuthenticationFlows
#idp.oidfed.admin.resolvertest.defaultAuthenticationMethods
#idp.oidfed.admin.resolvertest.TrustChainMetadataCache = shibboleth.oidfed.TrustChainMetadataCache
+#idp.oidfed.admin.resolvertest.EntityConfigurationMetadataCache = shibboleth.oidfed.EntityConfigurationMetadataCache
+#idp.oidfed.admin.resolvertest.LocalTrustAnchorsMetadataCache = shibboleth.oidfed.LocalTrustAnchorsMetadataCache
#idp.oidfed.admin.resolvertest.TrustMarkStatusMetadataCache = shibboleth.oidfed.TrustMarkStatusMetadataCache
+#idp.oidfed.admin.resolvertest.TrustedTrustMarkIssuersOnlyCondition = shibboleth.Conditions.TRUE
# resolve-entity-beans
#idp.oidfed.resolveEntity.authn.flows = OAuth2Client
@@ -141,6 +144,8 @@ idp.oidfed.entityConfiguration.authorityHints = https://your.authority.example.o
#idp.oidfed.resolveEntity.MetadataPolicyMergingStrategy = MetadataPolicyMergingStrategy
#idp.oidfed.resolveEntity.LocalMetadataPolicyStrategy = DefaultLocalMetadataPolicyStrategy
#idp.oidfed.resolveEntity.TrustChainMetadataCache = shibboleth.oidfed.TrustChainMetadataCache
+#idp.oidfed.resolveEntity.EntityConfigurationMetadataCache = shibboleth.oidfed.EntityConfigurationMetadataCache
+#idp.oidfed.resolveEntity.LocalTrustAnchorsMetadataCache = shibboleth.oidfed.LocalTrustAnchorsMetadataCache
#idp.oidfed.resolveEntity.TrustMarkStatusMetadataCache = shibboleth.oidfed.TrustMarkStatusMetadataCache
#idp.oidfed.resolveEntity.sigalg = RS256
#idp.oidfed.resolveEntity.endpointAuthMethods = private_key_jwt
@@ -148,3 +153,4 @@ idp.oidfed.entityConfiguration.authorityHints = https://your.authority.example.o
#idp.oidfed.resolveEntity.requireSingleJWTAudience = true
#idp.oidfed.resolveEntity.trustchain.resolver.useResolverApiCondition = shibboleth.Conditions.FALSE
#idp.oidfed.resolveEntity.trustchain.resolver.fallbackToLocalCondition = shibboleth.Conditions.TRUE
+#idp.oidfed.resolveEntity.TrustedTrustMarkIssuersOnlyCondition = shibboleth.Conditions.TRUE
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list