[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