[java-idp-plugin-oidc-op-oidfed] branch dev/CACHE-REFACTOR updated: Initial support for the metadata_policy_crit claim in subordinate statements
Codeberg
noreply at shibboleth.net
Mon Jan 26 09:11:58 UTC 2026
This is an automated email from the git hooks/post-receive script.
codeberg pushed a commit to branch dev/CACHE-REFACTOR
in repository java-idp-plugin-oidc-op-oidfed.
View the commit online:
https://codeberg.org/Shibboleth/java-idp-plugin-oidc-op-oidfed/commit/8976a093a143ebb181c39f7ba01805997b519d63
The following commit(s) were added to refs/heads/dev/CACHE-REFACTOR by this push:
new 8976a09 Initial support for the metadata_policy_crit claim in subordinate statements
8976a09 is described below
commit 8976a093a143ebb181c39f7ba01805997b519d63
Author: Henri Mikkonen <henri.mikkonen at iki.fi>
AuthorDate: Mon Jan 26 11:11:17 2026 +0200
Initial support for the metadata_policy_crit claim in subordinate statements
- Add getOperatorName() method to the federation metadata policy operators to identify the operator
- Refactored DefaultEntityStatementContentValidationCondition to be able to feed PRC to claims validators
- PRC is fetched via HttpServletRequest attributes (default binding key)
- MetadataPolicyCritClaimsValidator expoits the list of supported operators
- List may be endpoint specific: the default function exploits inbound message class (via PRC) for supplying the desired list
- The global default may be defined via idp.oidfed.authorize.MetadataPolicyOperators (automatic registration)
- Resolve Entity: idp.oidfed.resolve-entity.MetadataPolicyOperators
- Explicit registration: idp.oidfed.register.MetadataPolicyOperators
- All default to shibboleth.oidfed.StandardMetadataPolicyOperators
---
...tEntityStatementContentValidationCondition.java | 45 ++++++++-
.../policy/FederationMetadataPolicyOperator.java | 8 ++
...DefaultFederationMetadataPolicyAddOperator.java | 6 ++
...ultFederationMetadataPolicyDefaultOperator.java | 6 ++
...tFederationMetadataPolicyEssentialOperator.java | 6 ++
...faultFederationMetadataPolicyOneOfOperator.java | 6 ++
...ltFederationMetadataPolicySubsetOfOperator.java | 6 ++
...FederationMetadataPolicySupersetOfOperator.java | 6 ++
...faultFederationMetadataPolicyValueOperator.java | 6 ++
...faultMetadataPolicyOperatorsLookupStrategy.java | 103 ++++++++++++++++++++
.../impl/MetadataPolicyCritClaimsValidator.java | 105 +++++++++++++++++++++
.../META-INF/net.shibboleth.idp/postconfig.xml | 28 +++++-
.../flow/oidfed/AbstractFederationFlowTest.java | 23 +++++
.../AuthorizeFlowAutomaticRegistrationTest.java | 19 ++++
.../profile/flow/oidfed/RegistrationFlowTest.java | 12 +++
.../profile/flow/oidfed/ResolveEntityFlowTest.java | 40 ++++++++
16 files changed, 417 insertions(+), 8 deletions(-)
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/cache/remote/DefaultEntityStatementContentValidationCondition.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/cache/remote/DefaultEntityStatementContentValidationCondition.java
index bdd173a..4513abe 100644
--- a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/cache/remote/DefaultEntityStatementContentValidationCondition.java
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/cache/remote/DefaultEntityStatementContentValidationCondition.java
@@ -15,6 +15,7 @@
package net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.cache.remote;
import java.text.ParseException;
+import java.util.Optional;
import java.util.function.BiPredicate;
import javax.annotation.Nonnull;
@@ -25,20 +26,24 @@ import org.slf4j.Logger;
import com.nimbusds.jwt.JWTClaimsSet;
+import jakarta.servlet.http.HttpServletRequest;
import net.shibboleth.oidc.jwt.claims.ClaimsValidator;
import net.shibboleth.oidc.jwt.claims.JWTValidationException;
import net.shibboleth.oidc.metadata.filter.MetadataFilterContext;
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;
+import net.shibboleth.shared.primitive.NonnullSupplier;
/**
* Default content validating filter for entity statement. Verifies that the
* {@link RemoteEntityConfigurationContainer#getEntityId()} matches with the subject of the entity statement and
- * validates the claims via configurable claims validator. Note that an empty {@link ProfileRequestContext} is fed to
- * the claims validator.
+ * validates the claims via configurable claims validator. The {@link ProfileRequestContext} that is fed to the claims
+ * validator is fetched from the {@link HttpServletRequest} attributes. An empty context is fed if the attribute was
+ * null.
*/
@ThreadSafeAfterInit
public class DefaultEntityStatementContentValidationCondition
@@ -52,6 +57,9 @@ public class DefaultEntityStatementContentValidationCondition
/** The claims validator to use for validating the entity statement claims. */
@NonnullAfterInit private ClaimsValidator claimsValidator;
+ /** Supplier for the Current HTTP request, if available. */
+ @NonnullAfterInit private NonnullSupplier<HttpServletRequest> httpServletRequestSupplier;
+
/**
* Set the claims validator to use for validating the entity statement claims.
*
@@ -62,6 +70,28 @@ public class DefaultEntityStatementContentValidationCondition
claimsValidator = Constraint.isNotNull(validator, "Claims validator cannot be null");
}
+ /**
+ * Set the current HTTP request Supplier.
+ *
+ * @param requestSupplier Supplier for the current HTTP request
+ */
+ public void setHttpServletRequestSupplier(@Nonnull final NonnullSupplier<HttpServletRequest> requestSupplier) {
+ checkSetterPreconditions();
+ httpServletRequestSupplier = Constraint.isNotNull(requestSupplier, "Http servlet request supplier cannot be null");
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected void doInitialize() throws ComponentInitializationException {
+ super.doInitialize();
+ if (claimsValidator == null) {
+ throw new ComponentInitializationException("Claims validator cannot be null");
+ }
+ if (httpServletRequestSupplier == null) {
+ throw new ComponentInitializationException("Http servlet request supplier cannot be null");
+ }
+ }
+
/** {@inheritDoc} */
@Override
public boolean test(@Nullable final BaseExpirableStatementContainer<?> responseContainer,
@@ -79,11 +109,20 @@ public class DefaultEntityStatementContentValidationCondition
wrapper.getParsedPayload().getSubject(), responseContainer.getEntityId());
return false;
}
+ final ProfileRequestContext profileRequestContext =
+ Optional.ofNullable(httpServletRequestSupplier.get().getAttribute(ProfileRequestContext.BINDING_KEY))
+ .filter(ProfileRequestContext.class::isInstance)
+ .map(ProfileRequestContext.class::cast)
+ .orElse(null);
+ if (profileRequestContext == null) {
+ log.warn("Could not resolve profile request context, supplying an empty one to claims validators");
+ }
try {
final JWTClaimsSet claimsSet = wrapper.getJwt().getJWTClaimsSet();
assert claimsSet != null;
- claimsValidator.validate(claimsSet, new ProfileRequestContext());
+ claimsValidator.validate(claimsSet,
+ profileRequestContext != null ? profileRequestContext : new ProfileRequestContext());
} catch (final JWTValidationException | ParseException e) {
log.warn("Claims validation failed for entity statement {}", responseContainer.getEntityId(), e);
return false;
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/policy/FederationMetadataPolicyOperator.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/policy/FederationMetadataPolicyOperator.java
index c6a367a..dbfd708 100644
--- a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/policy/FederationMetadataPolicyOperator.java
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/policy/FederationMetadataPolicyOperator.java
@@ -18,6 +18,7 @@ import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import net.shibboleth.oidc.metadata.policy.MetadataPolicy;
+import net.shibboleth.shared.annotation.constraint.NotEmpty;
import net.shibboleth.shared.logic.ConstraintViolationException;
/**
@@ -27,6 +28,13 @@ import net.shibboleth.shared.logic.ConstraintViolationException;
*/
public interface FederationMetadataPolicyOperator {
+ /**
+ * The unique case-sensitive name of this operator.
+ *
+ * @return the operator name.
+ */
+ @Nonnull @NotEmpty public String getOperatorName();
+
/**
* Validate whether the operator is compatible with the other operators in the policy.
*
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/policy/impl/DefaultFederationMetadataPolicyAddOperator.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/policy/impl/DefaultFederationMetadataPolicyAddOperator.java
index e30ffc4..0995e74 100644
--- a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/policy/impl/DefaultFederationMetadataPolicyAddOperator.java
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/policy/impl/DefaultFederationMetadataPolicyAddOperator.java
@@ -25,6 +25,7 @@ import org.slf4j.Logger;
import net.shibboleth.oidc.metadata.policy.MetadataPolicy;
import net.shibboleth.oidc.metadata.policy.impl.MetadataPolicyHelper;
+import net.shibboleth.shared.annotation.constraint.NotEmpty;
import net.shibboleth.shared.collection.CollectionSupport;
import net.shibboleth.shared.logic.ConstraintViolationException;
import net.shibboleth.shared.primitive.LoggerFactory;
@@ -37,6 +38,11 @@ public class DefaultFederationMetadataPolicyAddOperator extends AbstractFederati
/** Class logger. */
@Nonnull private final Logger log = LoggerFactory.getLogger(DefaultFederationMetadataPolicyAddOperator.class);
+ /** {@inheritDoc} */
+ @Nonnull @NotEmpty public String getOperatorName() {
+ return "add";
+ }
+
/** {@inheritDoc} */
@Override
@Nullable public Object apply(@Nullable final Object candidate, @Nonnull final MetadataPolicy policy)
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/policy/impl/DefaultFederationMetadataPolicyDefaultOperator.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/policy/impl/DefaultFederationMetadataPolicyDefaultOperator.java
index 89bf483..f0ebe6b 100644
--- a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/policy/impl/DefaultFederationMetadataPolicyDefaultOperator.java
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/policy/impl/DefaultFederationMetadataPolicyDefaultOperator.java
@@ -18,6 +18,7 @@ import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import net.shibboleth.oidc.metadata.policy.MetadataPolicy;
+import net.shibboleth.shared.annotation.constraint.NotEmpty;
import net.shibboleth.shared.logic.ConstraintViolationException;
/**
@@ -25,6 +26,11 @@ import net.shibboleth.shared.logic.ConstraintViolationException;
*/
public class DefaultFederationMetadataPolicyDefaultOperator extends AbstractFederationMetadataPolicyOperator {
+ /** {@inheritDoc} */
+ @Nonnull @NotEmpty public String getOperatorName() {
+ return "default";
+ }
+
/** {@inheritDoc} */
@Override
@Nullable public Object apply(@Nullable final Object candidate, @Nonnull final MetadataPolicy policy)
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/policy/impl/DefaultFederationMetadataPolicyEssentialOperator.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/policy/impl/DefaultFederationMetadataPolicyEssentialOperator.java
index 8a1efc7..3167a63 100644
--- a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/policy/impl/DefaultFederationMetadataPolicyEssentialOperator.java
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/policy/impl/DefaultFederationMetadataPolicyEssentialOperator.java
@@ -18,6 +18,7 @@ import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import net.shibboleth.oidc.metadata.policy.MetadataPolicy;
+import net.shibboleth.shared.annotation.constraint.NotEmpty;
import net.shibboleth.shared.logic.ConstraintViolationException;
/**
@@ -25,6 +26,11 @@ import net.shibboleth.shared.logic.ConstraintViolationException;
*/
public class DefaultFederationMetadataPolicyEssentialOperator extends AbstractFederationMetadataPolicyOperator {
+ /** {@inheritDoc} */
+ @Nonnull @NotEmpty public String getOperatorName() {
+ return "essential";
+ }
+
/** {@inheritDoc} */
@Override
@Nullable public Object apply(@Nullable final Object candidate, @Nonnull final MetadataPolicy policy)
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/policy/impl/DefaultFederationMetadataPolicyOneOfOperator.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/policy/impl/DefaultFederationMetadataPolicyOneOfOperator.java
index 04a39f0..5165e0b 100644
--- a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/policy/impl/DefaultFederationMetadataPolicyOneOfOperator.java
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/policy/impl/DefaultFederationMetadataPolicyOneOfOperator.java
@@ -22,6 +22,7 @@ import javax.annotation.Nullable;
import org.slf4j.Logger;
import net.shibboleth.oidc.metadata.policy.MetadataPolicy;
+import net.shibboleth.shared.annotation.constraint.NotEmpty;
import net.shibboleth.shared.logic.ConstraintViolationException;
import net.shibboleth.shared.primitive.LoggerFactory;
@@ -33,6 +34,11 @@ public class DefaultFederationMetadataPolicyOneOfOperator extends AbstractFedera
/** Class logger. */
@Nonnull private final Logger log = LoggerFactory.getLogger(DefaultFederationMetadataPolicyOneOfOperator.class);
+ /** {@inheritDoc} */
+ @Nonnull @NotEmpty public String getOperatorName() {
+ return "one_of";
+ }
+
/** {@inheritDoc} */
@Override
@Nullable public Object apply(@Nullable final Object candidate, @Nonnull final MetadataPolicy policy)
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/policy/impl/DefaultFederationMetadataPolicySubsetOfOperator.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/policy/impl/DefaultFederationMetadataPolicySubsetOfOperator.java
index f5a05be..1668048 100644
--- a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/policy/impl/DefaultFederationMetadataPolicySubsetOfOperator.java
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/policy/impl/DefaultFederationMetadataPolicySubsetOfOperator.java
@@ -23,6 +23,7 @@ import org.slf4j.Logger;
import net.shibboleth.oidc.metadata.policy.MetadataPolicy;
import net.shibboleth.oidc.metadata.policy.impl.MetadataPolicyHelper;
+import net.shibboleth.shared.annotation.constraint.NotEmpty;
import net.shibboleth.shared.collection.CollectionSupport;
import net.shibboleth.shared.logic.ConstraintViolationException;
import net.shibboleth.shared.primitive.LoggerFactory;
@@ -35,6 +36,11 @@ public class DefaultFederationMetadataPolicySubsetOfOperator extends AbstractFed
/** Class logger. */
@Nonnull private final Logger log = LoggerFactory.getLogger(DefaultFederationMetadataPolicySubsetOfOperator.class);
+ /** {@inheritDoc} */
+ @Nonnull @NotEmpty public String getOperatorName() {
+ return "subset_of";
+ }
+
/** {@inheritDoc} */
@Override
@Nullable public Object apply(@Nullable final Object candidate, @Nonnull final MetadataPolicy policy)
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/policy/impl/DefaultFederationMetadataPolicySupersetOfOperator.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/policy/impl/DefaultFederationMetadataPolicySupersetOfOperator.java
index 5cea512..fae223e 100644
--- a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/policy/impl/DefaultFederationMetadataPolicySupersetOfOperator.java
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/policy/impl/DefaultFederationMetadataPolicySupersetOfOperator.java
@@ -23,6 +23,7 @@ import org.slf4j.Logger;
import net.shibboleth.oidc.metadata.policy.MetadataPolicy;
import net.shibboleth.oidc.metadata.policy.impl.MetadataPolicyHelper;
+import net.shibboleth.shared.annotation.constraint.NotEmpty;
import net.shibboleth.shared.collection.CollectionSupport;
import net.shibboleth.shared.logic.ConstraintViolationException;
import net.shibboleth.shared.primitive.LoggerFactory;
@@ -35,6 +36,11 @@ public class DefaultFederationMetadataPolicySupersetOfOperator extends AbstractF
/** Class logger. */
@Nonnull private final Logger log = LoggerFactory.getLogger(DefaultFederationMetadataPolicySupersetOfOperator.class);
+ /** {@inheritDoc} */
+ @Nonnull @NotEmpty public String getOperatorName() {
+ return "superset_of";
+ }
+
/** {@inheritDoc} */
@Override
@Nullable public Object apply(@Nullable final Object candidate, @Nonnull final MetadataPolicy policy)
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/policy/impl/DefaultFederationMetadataPolicyValueOperator.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/policy/impl/DefaultFederationMetadataPolicyValueOperator.java
index fee597c..6fdaefb 100644
--- a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/policy/impl/DefaultFederationMetadataPolicyValueOperator.java
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/policy/impl/DefaultFederationMetadataPolicyValueOperator.java
@@ -24,6 +24,7 @@ import org.slf4j.Logger;
import net.shibboleth.oidc.metadata.policy.MetadataPolicy;
import net.shibboleth.oidc.metadata.policy.impl.MetadataPolicyHelper;
+import net.shibboleth.shared.annotation.constraint.NotEmpty;
import net.shibboleth.shared.logic.ConstraintViolationException;
import net.shibboleth.shared.primitive.LoggerFactory;
@@ -35,6 +36,11 @@ public class DefaultFederationMetadataPolicyValueOperator extends AbstractFedera
/** Class logger. */
@Nonnull private final Logger log = LoggerFactory.getLogger(DefaultFederationMetadataPolicyValueOperator.class);
+ /** {@inheritDoc} */
+ @Nonnull @NotEmpty public String getOperatorName() {
+ return "value";
+ }
+
/** {@inheritDoc} */
@Override
@Nullable public Object apply(@Nullable final Object candidate, @Nonnull final MetadataPolicy policy)
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/security/jwt/claims/impl/DefaultMetadataPolicyOperatorsLookupStrategy.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/security/jwt/claims/impl/DefaultMetadataPolicyOperatorsLookupStrategy.java
new file mode 100644
index 0000000..8788bdd
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/security/jwt/claims/impl/DefaultMetadataPolicyOperatorsLookupStrategy.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.security.jwt.claims.impl;
+
+import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.opensaml.profile.context.ProfileRequestContext;
+import org.slf4j.Logger;
+
+import net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.policy.FederationMetadataPolicyOperator;
+import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
+import net.shibboleth.shared.component.AbstractIdentifiableInitializableComponent;
+import net.shibboleth.shared.component.ComponentInitializationException;
+import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
+
+/**
+ * Default lookup strategy to resolve list of supported metadata policy operators.
+ */
+public class DefaultMetadataPolicyOperatorsLookupStrategy extends AbstractIdentifiableInitializableComponent
+ implements Function<ProfileRequestContext, List<FederationMetadataPolicyOperator>> {
+
+ /** Class logger. */
+ @Nonnull private Logger log = LoggerFactory.getLogger(DefaultMetadataPolicyOperatorsLookupStrategy.class);
+
+ /** Map of supported operators by inbound message class name. */
+ @NonnullAfterInit private Map<String, List<FederationMetadataPolicyOperator>> supportedOperators;
+
+ /** List of default supported operators if inbound message class name was not mapped. */
+ @NonnullAfterInit private List<FederationMetadataPolicyOperator> defaultSupportedOperators;
+
+ /**
+ * Set the map of supported operators by inbound message class name.
+ *
+ * @param operators map of supported operators
+ */
+ public void setSupportedOperators(@Nonnull final Map<String, List<FederationMetadataPolicyOperator>> operators) {
+ checkSetterPreconditions();
+ supportedOperators = Constraint.isNotNull(operators, "Map of supported operators cannot be null");
+ }
+
+ /**
+ * Set the list of default supported operators if inbound message class name was not mapped.
+ *
+ * @param operators default list of supported operators
+ */
+ public void setDefaultSupportedOperators(@Nonnull List<FederationMetadataPolicyOperator> operators) {
+ checkSetterPreconditions();
+ defaultSupportedOperators =
+ Constraint.isNotNull(operators, "Default list of supported operators cannot be null");
+ }
+
+ /** {@inheritDoc} */
+ protected void doInitialize() throws ComponentInitializationException {
+ super.doInitialize();
+ if (supportedOperators == null) {
+ throw new ComponentInitializationException("Map of supported operators cannot be null");
+ }
+ if (defaultSupportedOperators == null) {
+ throw new ComponentInitializationException("Default list of supported operators cannot be null");
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override @Nullable
+ public List<FederationMetadataPolicyOperator> apply(@Nullable final ProfileRequestContext profileRequestContext) {
+ checkComponentActive();
+ if (profileRequestContext == null || profileRequestContext.getInboundMessageContext() == null
+ || profileRequestContext.ensureInboundMessageContext().getMessage() == null) {
+ log.warn("No inbound message resolved, returning default list of supported operators");
+ } else {
+ final Object message = profileRequestContext.ensureInboundMessageContext().getMessage();
+ assert message != null;
+ final String messageClassName = message.getClass().getCanonicalName();
+ if (supportedOperators.containsKey(messageClassName)) {
+ log.debug("Found message {} specific list of supported operators {}", messageClassName,
+ supportedOperators.get(messageClassName));
+ return supportedOperators.get(messageClassName);
+ }
+ log.trace("No messsage class {} specific list found, returning default list of supported operators",
+ messageClassName);
+ }
+ return defaultSupportedOperators;
+ }
+
+}
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/security/jwt/claims/impl/MetadataPolicyCritClaimsValidator.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/security/jwt/claims/impl/MetadataPolicyCritClaimsValidator.java
new file mode 100644
index 0000000..d28a348
--- /dev/null
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/security/jwt/claims/impl/MetadataPolicyCritClaimsValidator.java
@@ -0,0 +1,105 @@
+/*
+ * 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.security.jwt.claims.impl;
+
+import java.text.ParseException;
+import java.util.List;
+import java.util.Optional;
+import java.util.function.Function;
+
+import javax.annotation.Nonnull;
+
+import org.opensaml.profile.context.ProfileRequestContext;
+
+import com.nimbusds.jwt.JWTClaimsSet;
+
+import net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.policy.FederationMetadataPolicyOperator;
+import net.shibboleth.oidc.jwt.claims.AbstractClaimsValidator;
+import net.shibboleth.oidc.jwt.claims.ClaimsValidator;
+import net.shibboleth.oidc.jwt.claims.JWTValidationException;
+import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
+import net.shibboleth.shared.annotation.constraint.ThreadSafeAfterInit;
+import net.shibboleth.shared.collection.CollectionSupport;
+import net.shibboleth.shared.component.ComponentInitializationException;
+import net.shibboleth.shared.logic.Constraint;
+
+/**
+ * A {@link ClaimsValidator} for validating that all the metadata_policy_crit is not an empty array and all the values
+ * are recognized by the resolved list of supported metadata policy operators.
+ */
+ at ThreadSafeAfterInit
+public class MetadataPolicyCritClaimsValidator extends AbstractClaimsValidator {
+
+ /** The list of standard operators that cannot be included in the metadata_policy_crit array. */
+ public static final List<String> STANDARD_OPERATORS = CollectionSupport.listOf(
+ "value", "add", "default", "one_of", "subset_of", "superset_of", "essential");
+
+ /** The lookup strategy for the list of supported metadata policy operators . */
+ @NonnullAfterInit private
+ Function<ProfileRequestContext, List<FederationMetadataPolicyOperator>> supportedOperatorsLookupStrategy;
+
+ /**
+ * Set the lookup strategy for the list of supported metadata policy operators.
+ *
+ * @param strategy lookup strategy
+ */
+ public void setSupportedOperatorsLookupStrategy(
+ @Nonnull final Function<ProfileRequestContext, List<FederationMetadataPolicyOperator>> strategy) {
+ checkSetterPreconditions();
+ supportedOperatorsLookupStrategy =
+ Constraint.isNotNull(strategy, "Supported metadata policy operators lookup strategy cannot be null");
+ }
+
+ /** {@inheritDoc} */
+ protected void doInitialize() throws ComponentInitializationException {
+ super.doInitialize();
+ if (supportedOperatorsLookupStrategy == null) {
+ throw new ComponentInitializationException(
+ "Supported metadata policy operators lookup strategy cannot be null");
+ }
+ }
+
+ /** {@inheritDoc} */
+ protected void doValidate(@Nonnull final JWTClaimsSet claims,
+ @Nonnull final ProfileRequestContext context) throws JWTValidationException {
+ final List<String> values;
+ try {
+ values = claims.getStringListClaim("metadata_policy_crit");
+ } catch (final ParseException e) {
+ throw new JWTValidationException("Could not parse metadata_policy_crit into a list of strings");
+ }
+ final List<String> supportedValues = Optional.ofNullable(supportedOperatorsLookupStrategy.apply(context))
+ .orElse(CollectionSupport.emptyList())
+ .stream().map(operator -> operator.getOperatorName()).toList();
+ if (values != null) {
+ if (values.isEmpty()) {
+ throw new JWTValidationException("Empty array is not allowed for metadata_policy_crit");
+ }
+ for (final String value : values) {
+ if (values.indexOf(value) != values.lastIndexOf(value)) {
+ throw new JWTValidationException(
+ "Claim " + value + " is included more than once in metadata_policy_crit");
+ }
+ if (STANDARD_OPERATORS.contains(value)) {
+ throw new JWTValidationException(
+ "Claim " + value + " is standard operator and is not allowed in metadata_policy_crit");
+ }
+ if (!supportedValues.contains(value)) {
+ throw new JWTValidationException( "Claim " + value + " is not recognized in metadata_policy_crit");
+ }
+ }
+ }
+ }
+}
diff --git a/idp-oidfed-op-impl/src/main/resources/META-INF/net.shibboleth.idp/postconfig.xml b/idp-oidfed-op-impl/src/main/resources/META-INF/net.shibboleth.idp/postconfig.xml
index 34c4020..1f74889 100644
--- a/idp-oidfed-op-impl/src/main/resources/META-INF/net.shibboleth.idp/postconfig.xml
+++ b/idp-oidfed-op-impl/src/main/resources/META-INF/net.shibboleth.idp/postconfig.xml
@@ -134,7 +134,8 @@
</property>
</bean>
<bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.cache.remote.DefaultEntityStatementContentValidationCondition"
- p:claimsValidator-ref="%{idp.oidfed.entityConfiguration.claimsValidator:shibboleth.oidfed.DefaultEntityConfigurationClaimsValidator}"/>
+ p:claimsValidator-ref="%{idp.oidfed.entityConfiguration.claimsValidator:shibboleth.oidfed.DefaultEntityConfigurationClaimsValidator}"
+ p:httpServletRequestSupplier-ref="shibboleth.HttpServletRequestSupplier"/>
</util:list>
</property>
</bean>
@@ -222,7 +223,8 @@
</property>
</bean>
<bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.cache.remote.DefaultEntityStatementContentValidationCondition"
- p:claimsValidator-ref="%{idp.oidfed.subordinateStatement.claimsValidator:shibboleth.oidfed.DefaultSubordinateStatementClaimsValidator}"/>
+ p:claimsValidator-ref="%{idp.oidfed.subordinateStatement.claimsValidator:shibboleth.oidfed.DefaultSubordinateStatementClaimsValidator}"
+ p:httpServletRequestSupplier-ref="shibboleth.HttpServletRequestSupplier"/>
</util:list>
</property>
</bean>
@@ -274,6 +276,19 @@
p:requiredClaims="jwks" />
<bean class="net.shibboleth.oidc.security.jwt.claims.impl.ExpiryClaimsValidator"
p:clockSkew="%{idp.policy.clockSkew:PT1M}" />
+ <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.security.jwt.claims.impl.MetadataPolicyCritClaimsValidator">
+ <property name="supportedOperatorsLookupStrategy">
+ <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.security.jwt.claims.impl.DefaultMetadataPolicyOperatorsLookupStrategy"
+ p:defaultSupportedOperators-ref="#{'%{idp.oidfed.authorize.MetadataPolicyOperators:shibboleth.oidfed.StandardMetadataPolicyOperators}'.trim()}">
+ <property name="supportedOperators">
+ <util:map>
+ <entry key="net.shibboleth.idp.plugin.oidc.op.oidfed.messaging.impl.ResolveEntityRequest" value-ref="#{'%{idp.oidfed.resolve-entity.MetadataPolicyOperators:shibboleth.oidfed.StandardMetadataPolicyOperators}'.trim()}" />
+ <entry key="net.shibboleth.idp.plugin.oidc.op.oidfed.messaging.impl.ExplicitClientRegistrationRequest" value-ref="#{'%{idp.oidfed.register.MetadataPolicyOperators:shibboleth.oidfed.StandardMetadataPolicyOperators}'.trim()}" />
+ </util:map>
+ </property>
+ </bean>
+ </property>
+ </bean>
<bean class="net.shibboleth.oidc.security.jwt.claims.impl.ProhibitedClaimsValidator"
p:prohibitedClaims="authority_hints" />
<bean class="net.shibboleth.oidc.security.jwt.claims.impl.ProhibitedClaimsValidator"
@@ -375,7 +390,8 @@
</property>
</bean>
<bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.cache.remote.DefaultEntityStatementContentValidationCondition"
- p:claimsValidator-ref="%{idp.oidfed.remoteResolver.claimsValidator:shibboleth.oidfed.DefaultResolveEntityResponseClaimsValidator}"/>
+ p:claimsValidator-ref="%{idp.oidfed.remoteResolver.claimsValidator:shibboleth.oidfed.DefaultResolveEntityResponseClaimsValidator}"
+ p:httpServletRequestSupplier-ref="shibboleth.HttpServletRequestSupplier"/>
</util:list>
</property>
</bean>
@@ -501,7 +517,8 @@
</property>
</bean>
<bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.cache.remote.DefaultEntityStatementContentValidationCondition"
- p:claimsValidator-ref="%{idp.oidfed.trustMarkStatus.claimsValidator:shibboleth.oidfed.DefaultTrustMarkStatusClaimsValidator}"/>
+ p:claimsValidator-ref="%{idp.oidfed.trustMarkStatus.claimsValidator:shibboleth.oidfed.DefaultTrustMarkStatusClaimsValidator}"
+ p:httpServletRequestSupplier-ref="shibboleth.HttpServletRequestSupplier"/>
</util:list>
</property>
</bean>
@@ -586,7 +603,8 @@
</property>
</bean>
<bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.cache.remote.DefaultEntityStatementContentValidationCondition"
- p:claimsValidator-ref="%{idp.oidfed.trustMark.claimsValidator:shibboleth.oidfed.DefaultTrustMarkClaimsValidator}"/>
+ p:claimsValidator-ref="%{idp.oidfed.trustMark.claimsValidator:shibboleth.oidfed.DefaultTrustMarkClaimsValidator}"
+ p:httpServletRequestSupplier-ref="shibboleth.HttpServletRequestSupplier"/>
</util:list>
</property>
</bean>
diff --git a/idp-oidfed-op-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/oidfed/AbstractFederationFlowTest.java b/idp-oidfed-op-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/oidfed/AbstractFederationFlowTest.java
index b56da5c..fb41140 100644
--- a/idp-oidfed-op-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/oidfed/AbstractFederationFlowTest.java
+++ b/idp-oidfed-op-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/oidfed/AbstractFederationFlowTest.java
@@ -390,13 +390,24 @@ public class AbstractFederationFlowTest extends AbstractOidcFlowTest {
return subordinateStatement(issuer, metadata, leafKey);
}
+ protected String subordinateStatement(final String issuer, final Map<String, Object> metadata,
+ final List<String> metadataPolicyCrit) {
+ return subordinateStatement(issuer, metadata, metadataPolicyCrit, leafKey);
+ }
+
protected String subordinateStatement(final String issuer, final Map<String, Object> metadata,
final JWK subjectKey) {
+ return subordinateStatement(issuer, metadata, null, subjectKey);
+ }
+
+ protected String subordinateStatement(final String issuer, final Map<String, Object> metadata,
+ final List<String> metadataPolicyCrit, final JWK subjectKey) {
final JWTClaimsSet claimsSet = new JWTClaimsSet.Builder().issuer(anchorId).subject(issuer)
.issueTime(Date.from(Instant.now()))
.expirationTime(Date.from(Instant.now().plusSeconds(300)))
.claim("jwks", new JWKSet(subjectKey).toJSONObject(true))
.claim("metadata", metadata)
+ .claim("metadata_policy_crit", metadataPolicyCrit)
.build();
final EntityStatement<?> rpConfiguration =
TrustChainTestUtil.entityStatement(JWSAlgorithm.RS256, trustedAnchorKey, claimsSet);
@@ -544,6 +555,18 @@ public class AbstractFederationFlowTest extends AbstractOidcFlowTest {
}
}
+ protected void rpConfigureMockHttpClientWithMetadataCrit(final String clientId, final List<String> crit) {
+ try {
+ mapResponse(entityConfigurationUrl(clientId), mockResponse(rpEntityConfiguration(clientId)));
+ mapResponse(entityConfigurationUrl(anchorId), mockResponse(trustedAnchorConfiguration()));
+ mapResponse(subordinateStatementUrl(anchorFetchEndpoint, clientId),
+ mockResponse(subordinateStatement(clientId, Map.of("openid_relying_party",
+ new OIDCClientMetadata().toJSONObject()), crit)));
+ } catch (UnsupportedOperationException | IOException | URISyntaxException e) {
+ Assert.fail("Could not initialize mock HTTP client", e);
+ }
+ }
+
protected void rpResolveEntityConfigureMockHttpClient(final String clientId) {
final OIDCClientMetadata metadata = new OIDCClientMetadata();
metadata.setRedirectionURI(URI.create(redirectUri));
diff --git a/idp-oidfed-op-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/oidfed/AuthorizeFlowAutomaticRegistrationTest.java b/idp-oidfed-op-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/oidfed/AuthorizeFlowAutomaticRegistrationTest.java
index 4ce2b70..f7f3ebd 100644
--- a/idp-oidfed-op-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/oidfed/AuthorizeFlowAutomaticRegistrationTest.java
+++ b/idp-oidfed-op-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/oidfed/AuthorizeFlowAutomaticRegistrationTest.java
@@ -53,6 +53,7 @@ import net.shibboleth.idp.plugin.oidc.op.profile.flow.AuthorizeFlowTest;
import net.shibboleth.idp.plugin.oidc.op.profile.logic.DefaultPushedAuthorizationRequestUriSerializationFunction;
import net.shibboleth.idp.plugin.oidc.op.token.support.AuthorizeCodeClaimsSet;
import net.shibboleth.idp.session.SessionException;
+import net.shibboleth.shared.collection.CollectionSupport;
import net.shibboleth.shared.collection.Pair;
import net.shibboleth.shared.component.ComponentInitializationException;
import net.shibboleth.shared.security.DataSealerException;
@@ -117,6 +118,24 @@ public class AuthorizeFlowAutomaticRegistrationTest extends AbstractFederationFl
Assert.assertEquals(unwrapTrustChainFromAuthorizeCode(successResponse), List.of(clientId, anchorId));
}
+ @Test
+ public void testWithValidTrustChain_signedRequestObject_emptyMetadataPolicyCrit()
+ throws IOException, UnsupportedOperationException, URISyntaxException {
+ final String clientId = uniqueClientId();
+ rpConfigureMockHttpClientWithMetadataCrit(clientId, CollectionSupport.emptyList());
+ final FlowExecutionResult result =
+ launchAuthenticationRequest(clientId, "openid profile", signedRequestObject(Map.of(
+ "iss", clientId,
+ "client_id", clientId,
+ "aud", issuer,
+ "exp", Instant.now().plus(Duration.ofMinutes(5)).toEpochMilli(),
+ "jti", UUID.randomUUID(),
+ "response_type", "code",
+ "scope", "openid profile",
+ "redirect_uri", redirectUri)));
+ Assert.assertEquals(result.getOutcome().getId(), "ErrorView");
+ }
+
@Test
public void testWithValidTrustChain_resolveApi_signedRequestObject()
throws IOException, UnsupportedOperationException, URISyntaxException {
diff --git a/idp-oidfed-op-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/oidfed/RegistrationFlowTest.java b/idp-oidfed-op-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/oidfed/RegistrationFlowTest.java
index b3e39cc..18c0314 100644
--- a/idp-oidfed-op-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/oidfed/RegistrationFlowTest.java
+++ b/idp-oidfed-op-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/oidfed/RegistrationFlowTest.java
@@ -51,6 +51,7 @@ import net.shibboleth.idp.plugin.oidc.op.oidfed.TrustChainTestUtil;
import net.shibboleth.idp.plugin.oidc.op.oidfed.messaging.impl.ExplicitClientRegistrationResponse;
import net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.EntityStatement;
import net.shibboleth.oidc.metadata.impl.BaseStorageServiceClientInformationComponent;
+import net.shibboleth.shared.collection.CollectionSupport;
import net.shibboleth.shared.collection.Pair;
/**
@@ -118,6 +119,17 @@ public class RegistrationFlowTest extends AbstractFederationFlowTest {
verifyAuthorizeEndpoint(clientId, redirectUri);
}
+ @Test
+ public void testValidEntityConfiguration_emptyMetadataPolicyCrit() throws Exception {
+ final String clientId = uniqueClientId();
+ rpConfigureMockHttpClientWithMetadataCrit(clientId, CollectionSupport.emptyList());
+ setRequest("POST", rpEntityConfiguration(clientId), "application/entity-statement+jwt");
+ final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
+ verify(federationHttpClient, times(0)).executeOpen(any(),
+ argThat(new RequestUriMatcher(entityConfigurationUrl(clientId))), any());
+ assertErrorCode(result, "invalid_client");
+ }
+
@Test
public void testValidEntityConfiguration_verifyPar() throws Exception {
final String clientId = uniqueClientId();
diff --git a/idp-oidfed-op-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/oidfed/ResolveEntityFlowTest.java b/idp-oidfed-op-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/oidfed/ResolveEntityFlowTest.java
index 05f1322..bd8a31d 100644
--- a/idp-oidfed-op-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/oidfed/ResolveEntityFlowTest.java
+++ b/idp-oidfed-op-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/oidfed/ResolveEntityFlowTest.java
@@ -14,6 +14,10 @@
package net.shibboleth.idp.plugin.oidc.op.profile.flow.oidfed;
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.time.Instant;
+import java.util.Date;
import java.util.List;
import java.util.Map;
@@ -22,10 +26,15 @@ import org.testng.Assert;
import org.testng.annotations.Test;
import com.nimbusds.jose.JOSEObjectType;
+import com.nimbusds.jose.JWSAlgorithm;
+import com.nimbusds.jose.jwk.JWKSet;
+import com.nimbusds.jwt.JWTClaimsSet;
import com.nimbusds.jwt.SignedJWT;
import com.nimbusds.oauth2.sdk.Response;
+import net.shibboleth.idp.plugin.oidc.op.oidfed.TrustChainTestUtil;
import net.shibboleth.idp.plugin.oidc.op.oidfed.messaging.impl.ResolveEntityResponse;
+import net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.EntityStatement;
import net.shibboleth.oidc.profile.messaging.JSONErrorResponse;
import net.minidev.json.JSONObject;
@@ -129,6 +138,37 @@ public class ResolveEntityFlowTest extends AbstractFederationFlowTest {
assertErrorCode(result, "invalid_metadata");
}
+ @Test
+ public void testOPWithTrustedTrustAnchor_emptyMetadataPolicyCrit() throws Exception {
+ request.setMethod("GET");
+ final String entityId = uniqueClientId();
+ final JWTClaimsSet claimsSet = new JWTClaimsSet.Builder().issuer(anchorId).subject(entityId)
+ .issueTime(Date.from(Instant.now()))
+ .expirationTime(Date.from(Instant.now().plusSeconds(300)))
+ .claim("jwks", new JWKSet(leafKey).toJSONObject(true))
+ .claim("metadata", Map.of("openid_provider", emptyOpMetadata(entityId).toJSONObject()))
+ .build();
+ final EntityStatement<?> subordinateStatement =
+ TrustChainTestUtil.entityStatement(JWSAlgorithm.RS256, trustedAnchorKey, claimsSet);
+ try {
+ mapResponse(entityConfigurationUrl(entityId), mockResponse(opEntityConfiguration(entityId)));
+ mapResponse(entityConfigurationUrl(anchorId), mockResponse(trustedAnchorConfiguration()));
+ mapResponse(subordinateStatementUrl(anchorFetchEndpoint, entityId),
+ mockResponse(subordinateStatement.getJwt().serialize()));
+ } catch (UnsupportedOperationException | IOException | URISyntaxException e) {
+ Assert.fail("Could not initialize mock HTTP client", e);
+ }
+ request.setQueryString("sub=" + entityId + "&trust_anchor=" + anchorId + "&entity_type=openid_provider");
+ final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
+ final ResolveEntityResponse parsedResponse =
+ parseSuccessResponse(result, ResolveEntityResponse.class);
+ final SignedJWT response = parsedResponse.getJWT();
+ Assert.assertEquals(response.getHeader().getType(), new JOSEObjectType("resolve-response+jwt"));
+ Assert.assertEquals(response.getJWTClaimsSet().getSubject(), entityId);
+ Assert.assertNotNull(response.getJWTClaimsSet().getClaim("metadata"));
+ Assert.assertNull(response.getJWTClaimsSet().getClaim("authority_hints"));
+ }
+
protected JSONErrorResponse parseErrorResponse(final FlowExecutionResult result) {
final Response response = parseResponse(result);
Assert.assertTrue(response instanceof JSONErrorResponse);
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list