[java-idp-oidc] 04/04: JOIDC-222 - Support for OpenID Federation

Henri Mikkonen henri.mikkonen at iki.fi
Fri Aug 8 12:18:26 UTC 2025


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

hjmikkon pushed a commit to branch dev/JOIDC-222
in repository java-idp-oidc.

View the commit online:
http://git.shibboleth.net/view/?p=java-idp-oidc.git;a=commit;h=5426143340172a90ba3ddaff0079cc4b33c4bf2d

commit 5426143340172a90ba3ddaff0079cc4b33c4bf2d
Author: Henri Mikkonen <henri.mikkonen at iki.fi>
AuthorDate: Fri Aug 8 15:17:47 2025 +0300

    JOIDC-222 - Support for OpenID Federation
    
    https://shibboleth.atlassian.net/browse/JOIDC-222
    
    Refactored wirings for the entity statement signature validation
    - Specific trust engines for entity configurations and subordinate statements
    - Delete obsolete TokenPayloadAsymmetricKeyTrustEngine
      - Exploit already existing ExplicitKeySignedJWTTrustEngine instead
---
 ...faultEntityConfigurationCredentialResolver.java |  87 +++++++++++++++
 .../DefaultEntityStatementCredentialResolver.java  | 123 ---------------------
 ...DefaultPayloadJOSEObjectCredentialResolver.java |  71 ++++++++++++
 ...aultSubordinateStatementCredentialResolver.java | 103 +++++++++++++++++
 .../TokenPayloadAsymmetricKeyTrustEngine.java      |  78 -------------
 .../META-INF/net.shibboleth.idp/postconfig.xml     |  54 +++++----
 .../oidc/metadata-lookup/metadata-lookup-beans.xml |  18 +--
 .../idp/flows/oidfed/register/register-beans.xml   |  41 ++-----
 .../oidfed/resolve-entity/resolve-entity-beans.xml |  18 +--
 9 files changed, 310 insertions(+), 283 deletions(-)

diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultEntityConfigurationCredentialResolver.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultEntityConfigurationCredentialResolver.java
new file mode 100644
index 00000000..a5f0f249
--- /dev/null
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultEntityConfigurationCredentialResolver.java
@@ -0,0 +1,87 @@
+/*
+ * 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 net.shibboleth.idp.plugin.oidc.op.oidfed.metadata;
+
+import java.util.Objects;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.opensaml.security.credential.Credential;
+import org.slf4j.Logger;
+
+import com.nimbusds.jose.jwk.JWKSet;
+import com.nimbusds.openid.connect.sdk.federation.entities.EntityStatement;
+
+import net.shibboleth.oidc.security.credential.impl.BasicJOSEObjectCredentialResolver;
+import net.shibboleth.shared.primitive.LoggerFactory;
+import net.shibboleth.shared.resolver.CriteriaSet;
+import net.shibboleth.shared.resolver.ResolverException;
+
+/**
+ * Resolves credentials from the jwks-claim located in the signed JWT (entity configuration) payload. The JWT is fetched
+ * via {@link SubjectEntityStatementCriterion}. If the JWT is not self-signed (i.e. it's a subordinate statement), a
+ * {@link ResolverException} is thrown.
+ */
+public class DefaultEntityConfigurationCredentialResolver extends BasicJOSEObjectCredentialResolver {
+
+    /** Logger. */
+    @Nonnull private final Logger log = LoggerFactory.getLogger(DefaultEntityConfigurationCredentialResolver.class);
+
+    /** {@inheritDoc} */
+    @Override
+    protected Iterable<Credential> resolveFromSource(@Nullable final CriteriaSet criteriaSet) throws ResolverException {
+        if (criteriaSet == null) {
+            throw new ResolverException("No criteria set supplied");
+        }
+
+        return parseJwkSet(criteriaSet).getKeys().stream()
+                .filter(Objects::nonNull)
+                .map(jwk -> buildJWKCredential(jwk, null))
+                .filter(Objects::nonNull)
+                .map(Credential.class::cast)
+                .toList();
+    }
+
+    /**
+     * Parses the JWKSet from the given criteria set.
+     * 
+     * @param criteriaSet criteria set containing source JWT for the JWKSet
+     * @return the JWKSet parsed from the JWT payload
+     * @throws ResolverException if the JWKSet could not be parsed or found
+     */
+    @Nonnull protected JWKSet parseJwkSet(@Nonnull final CriteriaSet criteriaSet) throws ResolverException {
+        final SubjectEntityStatementCriterion subjectCriterion = criteriaSet.get(SubjectEntityStatementCriterion.class);
+        if (subjectCriterion == null) {
+            log.debug("No mandatory SubjectEntityStatementCriterion criteria supplied, resolver could not process");
+            throw new ResolverException(
+                    "Credential criteria set did not contain an instance of SubjectEntityStatementCriterion");
+        }
+        final JWKSet jwks;
+        final EntityStatement subjectStatement = subjectCriterion.getValue();
+        if (subjectStatement.getEntityID().getValue().equals(
+                subjectStatement.getClaimsSet().getIssuer().getValue())) {
+                    jwks = subjectStatement.getClaimsSet().getJWKSet();;
+        } else {
+            throw new ResolverException(
+                    "Unexpected contents in the SubjectEntityStatementCriterion: subject does not match issuer");
+        }
+
+        if (jwks == null || jwks.isEmpty()) {
+            throw new ResolverException("Could not parse mandatory jwks");
+        }
+        return jwks;
+    }
+}
diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultEntityStatementCredentialResolver.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultEntityStatementCredentialResolver.java
deleted file mode 100644
index a85cb99a..00000000
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultEntityStatementCredentialResolver.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * 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 net.shibboleth.idp.plugin.oidc.op.oidfed.metadata;
-
-import java.text.ParseException;
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-
-import org.opensaml.security.credential.Credential;
-import org.slf4j.Logger;
-
-import com.nimbusds.jose.JOSEObject;
-import com.nimbusds.jose.jwk.JWK;
-import com.nimbusds.jose.jwk.JWKSet;
-import com.nimbusds.jwt.SignedJWT;
-import com.nimbusds.openid.connect.sdk.federation.entities.EntityStatement;
-
-import net.shibboleth.oidc.security.credential.impl.BasicJOSEObjectCredentialResolver;
-import net.shibboleth.oidc.security.jose.criterion.JOSEObjectCriterion;
-import net.shibboleth.shared.primitive.LoggerFactory;
-import net.shibboleth.shared.resolver.CriteriaSet;
-import net.shibboleth.shared.resolver.ResolverException;
-
-/**
- * Resolves credentials from the jwks-claim located in the signed JWT (entity statement) payload. The JWT is fetched
- * via {@link SubjectEntityStatementCriterion} if it exists in the criteria set. If the JWT is not self-signed (i.e.
- * it's a subordinate statement), the jwks-claim is fetched from the signer's statement fetched via
- * {@link IssuerEntityStatementCriterion}.
- * 
- * If the {@link SubjectEntityStatementCriterion} doesn't exist, the JWT is fetched via {@link JOSEObjectCriterion}.
- */
-public class DefaultEntityStatementCredentialResolver extends BasicJOSEObjectCredentialResolver {
-
-    /** Logger. */
-    @Nonnull private final Logger log = LoggerFactory.getLogger(DefaultEntityStatementCredentialResolver.class);
-
-    /** {@inheritDoc} */
-    @Override
-    protected Iterable<Credential> resolveFromSource(@Nullable final CriteriaSet criteriaSet) throws ResolverException {
-        if (criteriaSet == null) {
-            throw new ResolverException("No criteria set supplied");
-        }
-
-        final JWKSet jwks = parseJwkSet(criteriaSet);
-        final List<Credential> credentials = new ArrayList<>();
-        for (final JWK jwk : jwks.getKeys()) {
-            if (jwk != null) {
-                final Credential cred = buildJWKCredential(jwk, null);
-                if (cred != null) {
-                    credentials.add(cred);
-                }
-            }
-        }
-        return credentials;
-    }
-
-    /**
-     * Parses the JWKSet from the given criteria set.
-     * 
-     * @param criteriaSet criteria set containing source JWT for the JWKSet
-     * @return the JWKSet parsed from the JWT payload
-     * @throws ResolverException if the JWKSet could not be parsed or found
-     */
-    @Nonnull protected JWKSet parseJwkSet(@Nonnull final CriteriaSet criteriaSet) throws ResolverException {
-        final SubjectEntityStatementCriterion subjectCriterion = criteriaSet.get(SubjectEntityStatementCriterion.class);
-        final JWKSet jwks;
-        if (subjectCriterion == null) {
-            log.debug("No SubjectEntityStatementCriterion criteria supplied, resolving from JOSEObject");
-            final JOSEObjectCriterion joseObjectCriteria = criteriaSet.get(JOSEObjectCriterion.class);
-            if (joseObjectCriteria == null) {
-                log.debug("No JOSEObject criteria supplied, resolver could not process");
-                throw new ResolverException("Credential criteria set did not contain an instance of "
-                        + "SubjectEntityStatementCriterion nor JOSEObjectCriterion");
-            }
-            final JOSEObject joseObject = joseObjectCriteria.getJOSEObject();
-            if (joseObject == null) {
-                throw new ResolverException("JOSEObjectCriterion did not contain an instance of JOSEObject");
-            }
-            try {
-                final SignedJWT jwt = SignedJWT.parse(joseObject.serialize());
-                jwks = JWKSet.parse(jwt.getJWTClaimsSet().getJSONObjectClaim("jwks"));
-            } catch (final ParseException e) {
-                throw new ResolverException("Could not parse JWKSet from JOSEObject", e);
-            }
-        } else {
-            final EntityStatement subjectStatement = subjectCriterion.getValue();
-            if (subjectStatement.getEntityID().getValue().equals(
-                    subjectStatement.getClaimsSet().getIssuer().getValue())) {
-                jwks = subjectStatement.getClaimsSet().getJWKSet();;
-            } else {
-                final IssuerEntityStatementCriterion issuerCriterion =
-                        criteriaSet.get(IssuerEntityStatementCriterion.class);
-                if (issuerCriterion == null) {
-                    log.debug("No mandatory IssuerEntityStatementCriterion supplied, resolver could not process");
-                    throw new ResolverException(
-                            "Credential criteria set did not contain an instance of IssuerEntityStatementCriterion");
-                }
-                final EntityStatement issuerStatement = issuerCriterion.getValue();
-                jwks = issuerStatement.getClaimsSet().getJWKSet();
-            }
-        }
-
-        if (jwks == null || jwks.isEmpty()) {
-            throw new ResolverException("Could not parse mandatory jwks");
-        }
-        return jwks;
-    }
-}
diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultPayloadJOSEObjectCredentialResolver.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultPayloadJOSEObjectCredentialResolver.java
new file mode 100644
index 00000000..99fc68be
--- /dev/null
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultPayloadJOSEObjectCredentialResolver.java
@@ -0,0 +1,71 @@
+/*
+ * 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 net.shibboleth.idp.plugin.oidc.op.oidfed.metadata;
+
+import java.text.ParseException;
+import java.util.Objects;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.opensaml.security.credential.Credential;
+import org.slf4j.Logger;
+
+import com.nimbusds.jose.JOSEObject;
+import com.nimbusds.jose.jwk.JWKSet;
+import com.nimbusds.jwt.SignedJWT;
+
+import net.shibboleth.oidc.security.credential.impl.BasicJOSEObjectCredentialResolver;
+import net.shibboleth.oidc.security.jose.criterion.JOSEObjectCriterion;
+import net.shibboleth.shared.primitive.LoggerFactory;
+import net.shibboleth.shared.resolver.CriteriaSet;
+import net.shibboleth.shared.resolver.ResolverException;
+
+/**
+ * Resolves credentials from the jwks-claim located in the signed JWT (entity statement) payload. The JWT is fetched
+ * via {@link JOSEObjectCriterion}.
+ */
+public class DefaultPayloadJOSEObjectCredentialResolver extends BasicJOSEObjectCredentialResolver {
+
+    /** Logger. */
+    @Nonnull private final Logger log = LoggerFactory.getLogger(DefaultPayloadJOSEObjectCredentialResolver.class);
+
+    /** {@inheritDoc} */
+    @Override
+    protected Iterable<Credential> resolveFromSource(@Nullable final CriteriaSet criteriaSet) throws ResolverException {
+        if (criteriaSet == null || !criteriaSet.contains(JOSEObjectCriterion.class)) {
+            throw new ResolverException("CriteriaSet does not contain JOSEObjectCriterion");
+        }
+
+        final JOSEObjectCriterion joseObjectCriteria = criteriaSet.get(JOSEObjectCriterion.class);
+        final JOSEObject joseObject = joseObjectCriteria.getJOSEObject();
+        if (joseObject == null) {
+            throw new ResolverException("JOSEObjectCriterion did not contain an instance of JOSEObject");
+        }
+        try {
+            final SignedJWT jwt = SignedJWT.parse(joseObject.serialize());
+            final JWKSet jwks = JWKSet.parse(jwt.getJWTClaimsSet().getJSONObjectClaim("jwks"));
+            return jwks.getKeys().stream()
+                    .filter(Objects::nonNull)
+                    .map(jwk -> buildJWKCredential(jwk, null))
+                    .filter(Objects::nonNull)
+                    .map(Credential.class::cast)
+                    .toList();
+        } catch (final ParseException e) {
+            throw new ResolverException("Could not parse JWKSet from JOSEObject", e);
+        }
+    }
+
+}
diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultSubordinateStatementCredentialResolver.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultSubordinateStatementCredentialResolver.java
new file mode 100644
index 00000000..62315281
--- /dev/null
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultSubordinateStatementCredentialResolver.java
@@ -0,0 +1,103 @@
+/*
+ * 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 net.shibboleth.idp.plugin.oidc.op.oidfed.metadata;
+
+import java.util.Objects;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.opensaml.security.credential.Credential;
+import org.slf4j.Logger;
+
+import com.nimbusds.jose.jwk.JWKSet;
+import com.nimbusds.openid.connect.sdk.federation.entities.EntityStatement;
+
+import net.shibboleth.oidc.security.credential.impl.BasicJOSEObjectCredentialResolver;
+import net.shibboleth.shared.primitive.LoggerFactory;
+import net.shibboleth.shared.resolver.CriteriaSet;
+import net.shibboleth.shared.resolver.ResolverException;
+
+/**
+ * Resolves credentials from the jwks-claim located in the signed JWT (issuer of a subordinate statement) payload.
+ * First, a JWT is fetched via {@link SubjectEntityStatementCriterion}. Its issuer must match with the entity
+ * statement fetched via {@link IssuerEntityStatementCriterion}. The issuer must be a self-signed statement.
+ */
+public class DefaultSubordinateStatementCredentialResolver extends BasicJOSEObjectCredentialResolver {
+
+    /** Logger. */
+    @Nonnull private final Logger log = LoggerFactory.getLogger(DefaultSubordinateStatementCredentialResolver.class);
+
+    /** {@inheritDoc} */
+    @Override
+    protected Iterable<Credential> resolveFromSource(@Nullable final CriteriaSet criteriaSet) throws ResolverException {
+        if (criteriaSet == null) {
+            throw new ResolverException("No criteria set supplied");
+        }
+
+        return parseJwkSet(criteriaSet).getKeys().stream()
+                .filter(Objects::nonNull)
+                .map(jwk -> buildJWKCredential(jwk, null))
+                .filter(Objects::nonNull)
+                .map(Credential.class::cast)
+                .toList();
+    }
+
+    /**
+     * Parses the JWKSet from the given criteria set.
+     * 
+     * @param criteriaSet criteria set containing source JWT for the JWKSet
+     * @return the JWKSet parsed from the JWT payload
+     * @throws ResolverException if the JWKSet could not be parsed or found
+     */
+    @Nonnull protected JWKSet parseJwkSet(@Nonnull final CriteriaSet criteriaSet) throws ResolverException {
+        final SubjectEntityStatementCriterion subjectCriterion = criteriaSet.get(SubjectEntityStatementCriterion.class);
+        if (subjectCriterion == null) {
+            log.debug("No mandatory SubjectEntityStatementCriterion criteria supplied, resolver could not process");
+            throw new ResolverException(
+                    "Credential criteria set did not contain an instance of SubjectEntityStatementCriterion");
+        }
+        final JWKSet jwks;
+        final EntityStatement subjectStatement = subjectCriterion.getValue();
+        if (subjectStatement.getEntityID().getValue().equals(
+                subjectStatement.getClaimsSet().getIssuer().getValue())) {
+            throw new ResolverException(
+                    "Unexpected contents in the SubjectEntityStatementCriterion: subject matches issuer");
+        } else {
+            final IssuerEntityStatementCriterion issuerCriterion =
+                    criteriaSet.get(IssuerEntityStatementCriterion.class);
+            if (issuerCriterion == null) {
+                log.debug("No mandatory IssuerEntityStatementCriterion supplied, resolver could not process");
+                throw new ResolverException(
+                        "Credential criteria set did not contain an instance of IssuerEntityStatementCriterion");
+            }
+            final EntityStatement issuerStatement = issuerCriterion.getValue();
+            if (!issuerStatement.getEntityID().getValue().equals(
+                    subjectStatement.getClaimsSet().getIssuer().getValue())) {
+                throw new ResolverException("Credential criteria do not match for subject and issuer");
+            }
+            if (!issuerStatement.getEntityID().getValue().equals(
+                    issuerStatement.getClaimsSet().getIssuer().getValue())) {
+                throw new ResolverException("Issuer entity statement is not self signed");
+            }
+            jwks = issuerStatement.getClaimsSet().getJWKSet();
+        }
+
+        if (jwks == null || jwks.isEmpty()) {
+            throw new ResolverException("Could not parse mandatory jwks");
+        }
+        return jwks;
+    }
+}
diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/TokenPayloadAsymmetricKeyTrustEngine.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/TokenPayloadAsymmetricKeyTrustEngine.java
deleted file mode 100644
index 3347fcaf..00000000
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/TokenPayloadAsymmetricKeyTrustEngine.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * 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 net.shibboleth.idp.plugin.oidc.op.oidfed.metadata;
-
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-
-import org.opensaml.security.SecurityException;
-import org.opensaml.security.credential.Credential;
-import org.slf4j.Logger;
-
-import com.nimbusds.jwt.SignedJWT;
-
-import net.shibboleth.oidc.security.credential.JOSEObjectCredentialResolver;
-import net.shibboleth.oidc.security.impl.BaseSignedJWTTrustEngine;
-import net.shibboleth.shared.annotation.ParameterName;
-import net.shibboleth.shared.primitive.LoggerFactory;
-import net.shibboleth.shared.resolver.CriteriaSet;
-import net.shibboleth.shared.resolver.ResolverException;
-
-public class TokenPayloadAsymmetricKeyTrustEngine extends BaseSignedJWTTrustEngine<Credential> {
-
-    /** Class logger. */
-    @Nonnull private final Logger log = LoggerFactory.getLogger(TokenPayloadAsymmetricKeyTrustEngine.class);
-
-    /** Resolver of credentials from JOSEObject. */
-    @Nonnull private final JOSEObjectCredentialResolver joseObjectCredentialResolver;
-
-    /**
-     * Constructor.
-     * 
-     * @param joseObjectResolver resolver of credentials from JOSEObject payload.
-     */
-    protected TokenPayloadAsymmetricKeyTrustEngine(
-            @Nonnull final @ParameterName(name="JOSEObjectResolver") JOSEObjectCredentialResolver joseObjectResolver) {
-        super(joseObjectResolver);
-        joseObjectCredentialResolver = joseObjectResolver;
-    }
-
-    @Override
-    /** {@inheritDoc} */
-    protected boolean doValidate(@Nonnull final SignedJWT signedJWT, @Nonnull final CriteriaSet trustBasisCriteria)
-            throws SecurityException {
-        try {
-            for (final Credential credential : joseObjectCredentialResolver.resolve(trustBasisCriteria)) {
-                assert credential != null;
-                if (verifySignature(signedJWT, credential)) {
-                    log.debug("Token successfully validated with credential {}", credential.getKeyNames());
-                    return true;
-                }
-            }
-        } catch (final ResolverException e) {
-            throw new SecurityException("Error resolving credentials from JOSEObject", e);
-        }
-
-        return false;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected boolean evaluateTrust(@Nonnull final Credential untrustedCredential,
-            @Nullable final Credential trustBasis) throws SecurityException {
-        throw new SecurityException("evaluateTrust-method not implemented");
-    }
-
-}
diff --git a/idp-oidc-extension-impl/src/main/resources/META-INF/net.shibboleth.idp/postconfig.xml b/idp-oidc-extension-impl/src/main/resources/META-INF/net.shibboleth.idp/postconfig.xml
index dd0c2d13..8ada0f86 100644
--- a/idp-oidc-extension-impl/src/main/resources/META-INF/net.shibboleth.idp/postconfig.xml
+++ b/idp-oidc-extension-impl/src/main/resources/META-INF/net.shibboleth.idp/postconfig.xml
@@ -1071,18 +1071,31 @@
             </bean>
         </property>
         <property name="metadataFilterStrategy">
-            <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.DefaultEntityStatementSignatureValidationFilterStrategy">
-                <property name="trustEngine">
-                    <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.TokenPayloadAsymmetricKeyTrustEngine">
-                        <constructor-arg>
-                            <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.DefaultEntityStatementCredentialResolver" />
-                         </constructor-arg>
-                    </bean>
-                </property>
-            </bean>
+            <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.DefaultEntityStatementSignatureValidationFilterStrategy"
+                p:trustEngine-ref="shibboleth.oidfed.DefaultEntityConfigurationTrustEngine"/>
         </property>
     </bean>
 
+    <bean id="shibboleth.oidfed.DefaultEntityConfigurationTrustEngine"
+        class="net.shibboleth.oidc.security.impl.ExplicitKeySignedJWTTrustEngine">
+        <constructor-arg index="0">
+            <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.DefaultEntityConfigurationCredentialResolver" />
+        </constructor-arg>
+        <constructor-arg index="1">
+            <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.DefaultPayloadJOSEObjectCredentialResolver" />
+        </constructor-arg>
+    </bean>
+
+    <bean id="shibboleth.oidfed.DefaultSubordinateStatementTrustEngine"
+        class="net.shibboleth.oidc.security.impl.ExplicitKeySignedJWTTrustEngine">
+        <constructor-arg index="0">
+            <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.DefaultSubordinateStatementCredentialResolver" />
+        </constructor-arg>
+        <constructor-arg index="1">
+            <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.DefaultPayloadJOSEObjectCredentialResolver" />
+        </constructor-arg>
+    </bean>
+
     <bean id="shibboleth.oidfed.DefaultSubjectEntityIDCriteriaToIdentifierStrategy"
         class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.DefaultSubjectEntityIDCriteriaToIdentifierStrategy" />
 
@@ -1107,15 +1120,8 @@
         </property>
         <property name="metadataFilterStrategy">
             <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.DefaultSubordinateStatementSignatureValidationFilterStrategy"
-                p:entityConfigurationCache-ref="shibboleth.oidfed.EntityConfigurationMetadataCache">
-                <property name="trustEngine">
-                    <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.TokenPayloadAsymmetricKeyTrustEngine">
-                        <constructor-arg>
-                            <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.DefaultEntityStatementCredentialResolver" />
-                        </constructor-arg>
-                    </bean>
-                </property>
-            </bean>
+                p:entityConfigurationCache-ref="shibboleth.oidfed.EntityConfigurationMetadataCache"
+                p:trustEngine-ref="shibboleth.oidfed.DefaultSubordinateStatementTrustEngine"/>
         </property>
         <property name="fetchStrategy">
             <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.DefaultEntityStatementFetchingStrategy"
@@ -1156,7 +1162,7 @@
                                         c:cache-ref="shibboleth.oidfed.LocalTrustAnchorsMetadataCache" />
                                  </constructor-arg>
                                  <constructor-arg index="1">
-                                     <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.DefaultEntityStatementCredentialResolver" />
+                                     <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.DefaultPayloadJOSEObjectCredentialResolver" />
                                  </constructor-arg>
                             </bean>
                         </property>
@@ -1220,6 +1226,16 @@
         </property>
     </bean>
 
+    <bean id="shibboleth.oidfed.DefaultDelegatedTrustMarkTrustEngine"
+        class="net.shibboleth.oidc.security.impl.ExplicitKeySignedJWTTrustEngine">
+        <constructor-arg index="0">
+            <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.DefaultTrustMarkOwnerCredentialResolver" />
+        </constructor-arg>
+        <constructor-arg index="1">
+            <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.DefaultPayloadJOSEObjectCredentialResolver" />
+        </constructor-arg>
+    </bean>
+
     <bean id="PreferFileSystemResourceLoader"
         class="net.shibboleth.shared.spring.resource.PreferFileSystemResourceLoader"/>
 
diff --git a/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidc/metadata-lookup/metadata-lookup-beans.xml b/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidc/metadata-lookup/metadata-lookup-beans.xml
index c30d807f..9d75fb66 100644
--- a/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidc/metadata-lookup/metadata-lookup-beans.xml
+++ b/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidc/metadata-lookup/metadata-lookup-beans.xml
@@ -163,21 +163,9 @@
         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('DefaultTrustMarkClaimsValidationLookupStrategy')}">
-        <property name="trustEngine">
-            <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.TokenPayloadAsymmetricKeyTrustEngine">
-                <constructor-arg>
-                    <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.DefaultEntityStatementCredentialResolver" />
-                 </constructor-arg>
-            </bean>
-        </property>
-        <property name="delegationTrustEngine">
-            <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.TokenPayloadAsymmetricKeyTrustEngine">
-                <constructor-arg>
-                    <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.DefaultTrustMarkOwnerCredentialResolver" />
-                 </constructor-arg>
-            </bean>
-        </property>
+        p:delegatedTrustMarkClaimsValidationLookupStrategy="#{getObject('shibboleth.oidfed.DelegatedTrustMarkClaimsValidationLookupStrategy') ?: getObject('DefaultTrustMarkClaimsValidationLookupStrategy')}"
+        p:trustEngine-ref="shibboleth.oidfed.DefaultEntityConfigurationTrustEngine"
+        p:delegationTrustEngine-ref="shibboleth.oidfed.DefaultDelegatedTrustMarkTrustEngine">
         <property name="trustedTrustMarkIssuersLookupStrategy">
             <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.DefaultTrustChainTrustedTrustMarkIssuersLookupStrategy"
                 p:objectMapper-ref="shibboleth.oidc.JSONObjectMapper" />
diff --git a/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidfed/register/register-beans.xml b/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidfed/register/register-beans.xml
index 082d9956..d27d3ca7 100644
--- a/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidfed/register/register-beans.xml
+++ b/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidfed/register/register-beans.xml
@@ -47,14 +47,8 @@
         <property name="providedTrustChainValidationStrategy">
             <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.DefaultProvidedTrustChainValidationStrategy"
                 p:federationPolicyConstraints-ref="%{idp.oidfed.FederationPolicyConstraints:shibboleth.oidfed.DefaultFederationPolicyConstraints}"
-                p:objectMapper-ref="shibboleth.oidfed.policy.JSONObjectMapper">
-                <property name="trustEngine">
-                    <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.TokenPayloadAsymmetricKeyTrustEngine">
-                        <constructor-arg>
-                            <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.DefaultEntityStatementCredentialResolver" />
-                        </constructor-arg>
-                    </bean>
-                </property>
+                p:objectMapper-ref="shibboleth.oidfed.policy.JSONObjectMapper"
+                p:trustEngine-ref="shibboleth.oidfed.DefaultEntityConfigurationTrustEngine">
                 <property name="trustAnchorSignatureValidationFilterStrategy">
                     <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.DefaultEntityStatementSignatureValidationFilterStrategy">
                         <property name="trustEngine">
@@ -64,7 +58,7 @@
                                         c:cache-ref="shibboleth.oidfed.LocalTrustAnchorsMetadataCache" />
                                  </constructor-arg>
                                  <constructor-arg index="1">
-                                     <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.DefaultEntityStatementCredentialResolver" />
+                                     <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.DefaultPayloadJOSEObjectCredentialResolver" />
                                  </constructor-arg>
                             </bean>
                         </property>
@@ -99,15 +93,8 @@
             <bean parent="shibboleth.Functions.Expression"
                 c:expression="#custom.apply(#input.ensureInboundMessageContext().getMessage().getEntityConfiguration(), null)">
                 <property name="customObject">
-                    <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.DefaultEntityStatementSignatureValidationFilterStrategy">
-                        <property name="trustEngine">
-                            <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.TokenPayloadAsymmetricKeyTrustEngine">
-                                <constructor-arg>
-                                    <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.DefaultEntityStatementCredentialResolver" />
-                                </constructor-arg>
-                            </bean>
-                        </property>
-                    </bean>
+                    <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.DefaultEntityStatementSignatureValidationFilterStrategy"
+                        p:trustEngine-ref="shibboleth.oidfed.DefaultEntityConfigurationTrustEngine"/>
                 </property>
             </bean>
         </property>
@@ -183,21 +170,9 @@
         scope="prototype"
         p:trustChainCache-ref="#{'%{idp.oidfed.register.TrustChainMetadataCache:shibboleth.oidfed.TrustChainMetadataCache}'.trim()}"
         p:trustMarkClaimsValidationLookupStrategy="#{getObject('shibboleth.oidfed.TrustMarkClaimsValidationLookupStrategy') ?: getObject('DefaultTrustMarkClaimsValidationLookupStrategy')}"
-        p:delegatedTrustMarkClaimsValidationLookupStrategy="#{getObject('shibboleth.oidfed.DelegatedTrustMarkClaimsValidationLookupStrategy') ?: getObject('DefaultTrustMarkClaimsValidationLookupStrategy')}">
-        <property name="trustEngine">
-            <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.TokenPayloadAsymmetricKeyTrustEngine">
-                <constructor-arg>
-                    <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.DefaultEntityStatementCredentialResolver" />
-                 </constructor-arg>
-            </bean>
-        </property>
-        <property name="delegationTrustEngine">
-            <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.TokenPayloadAsymmetricKeyTrustEngine">
-                <constructor-arg>
-                    <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.DefaultTrustMarkOwnerCredentialResolver" />
-                 </constructor-arg>
-            </bean>
-        </property>
+        p:delegatedTrustMarkClaimsValidationLookupStrategy="#{getObject('shibboleth.oidfed.DelegatedTrustMarkClaimsValidationLookupStrategy') ?: getObject('DefaultTrustMarkClaimsValidationLookupStrategy')}"
+        p:trustEngine-ref="shibboleth.oidfed.DefaultEntityConfigurationTrustEngine"
+        p:delegationTrustEngine-ref="shibboleth.oidfed.DefaultDelegatedTrustMarkTrustEngine">
         <property name="trustedTrustMarkIssuersLookupStrategy">
             <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.DefaultTrustChainTrustedTrustMarkIssuersLookupStrategy"
                 p:objectMapper-ref="shibboleth.oidc.JSONObjectMapper" />
diff --git a/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidfed/resolve-entity/resolve-entity-beans.xml b/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidfed/resolve-entity/resolve-entity-beans.xml
index f9606281..e9bf3c4f 100644
--- a/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidfed/resolve-entity/resolve-entity-beans.xml
+++ b/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidfed/resolve-entity/resolve-entity-beans.xml
@@ -128,21 +128,9 @@
         scope="prototype"
         p:trustChainCache-ref="#{'%{idp.oidfed.resolve-entity.TrustChainMetadataCache:shibboleth.oidfed.TrustChainMetadataCache}'.trim()}"
         p:trustMarkClaimsValidationLookupStrategy="#{getObject('shibboleth.oidfed.TrustMarkClaimsValidationLookupStrategy') ?: getObject('DefaultTrustMarkClaimsValidationLookupStrategy')}"
-        p:delegatedTrustMarkClaimsValidationLookupStrategy="#{getObject('shibboleth.oidfed.DelegatedTrustMarkClaimsValidationLookupStrategy') ?: getObject('DefaultTrustMarkClaimsValidationLookupStrategy')}">
-        <property name="trustEngine">
-            <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.TokenPayloadAsymmetricKeyTrustEngine">
-                <constructor-arg>
-                    <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.DefaultEntityStatementCredentialResolver" />
-                 </constructor-arg>
-            </bean>
-        </property>
-        <property name="delegationTrustEngine">
-            <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.TokenPayloadAsymmetricKeyTrustEngine">
-                <constructor-arg>
-                    <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.DefaultTrustMarkOwnerCredentialResolver" />
-                 </constructor-arg>
-            </bean>
-        </property>
+        p:delegatedTrustMarkClaimsValidationLookupStrategy="#{getObject('shibboleth.oidfed.DelegatedTrustMarkClaimsValidationLookupStrategy') ?: getObject('DefaultTrustMarkClaimsValidationLookupStrategy')}"
+        p:trustEngine-ref="shibboleth.oidfed.DefaultEntityConfigurationTrustEngine"
+        p:delegationTrustEngine-ref="shibboleth.oidfed.DefaultDelegatedTrustMarkTrustEngine">
         <property name="trustedTrustMarkIssuersLookupStrategy">
             <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.DefaultTrustChainTrustedTrustMarkIssuersLookupStrategy"
                 p:objectMapper-ref="shibboleth.oidc.JSONObjectMapper" />

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


More information about the commits mailing list