[java-idp-plugin-oidc-op-oidfed] 02/03: Include metadata-claim parsing for Jackson

Codeberg noreply at shibboleth.net
Thu Dec 18 17:55:47 UTC 2025


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/25a9758a12ff8d426f3b065a7c393978e3269ed6

commit 25a9758a12ff8d426f3b065a7c393978e3269ed6
Author: Henri Mikkonen <henri.mikkonen at iki.fi>
AuthorDate: Thu Dec 18 19:11:58 2025 +0200

    Include metadata-claim parsing for Jackson
    
    - Simplifies access to the metadata of the standardized entity types
---
 .../op/oidfed/metadata/EntityStatementPayload.java |  12 +-
 .../oidc/op/oidfed/metadata/claim/Metadata.java    | 267 +++++++++++++++++++++
 .../context/RelyingPartyTrustChainContext.java     |  13 +-
 ...mbinedMetadataFromTrustChainLookupStrategy.java |   6 +-
 ...efaultSubordinateStatementFetchingStrategy.java |   2 +-
 .../impl/DefaultAllowedEntityTypesConstraint.java  |  21 +-
 .../metadata/util/EntityStatementHelper.java       |   2 +-
 .../impl/AbstractTrustChainResolutionAction.java   |   5 +-
 .../impl/AddExtensionsToClientInformation.java     |   3 +-
 .../profile/impl/BuildResolveEntityResponse.java   |   7 +-
 .../oidfed/profile/impl/CallResolveEntityApi.java  |   9 +-
 .../op/oidfed/profile/impl/ResolveTrustChains.java |   4 +-
 .../op/oidfed/profile/impl/ResolveTrustMarks.java  |   4 +-
 .../op/oidfed/profile/impl/SelectTrustChain.java   |   8 +-
 .../profile/impl/StoreAutomaticRegistration.java   |   5 +-
 ...eAutomaticRegistrationProfileConfiguration.java |   7 +-
 .../profile/impl/ValidateProvidedTrustChain.java   |   3 +-
 .../profile/impl/ValidateSelectedTrustChain.java   |   6 +-
 ...ltSelectedTrustChainMetadataLookupStrategy.java |   9 +-
 .../DefaultTrustChainSelectionStrategy.java        |   8 +-
 20 files changed, 337 insertions(+), 64 deletions(-)

diff --git a/idp-oidfed-op-api/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/EntityStatementPayload.java b/idp-oidfed-op-api/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/EntityStatementPayload.java
index bd9c9ec..07cb269 100644
--- a/idp-oidfed-op-api/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/EntityStatementPayload.java
+++ b/idp-oidfed-op-api/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/EntityStatementPayload.java
@@ -25,6 +25,8 @@ import com.fasterxml.jackson.annotation.JsonProperty;
 import com.google.common.base.MoreObjects;
 import com.nimbusds.jose.jwk.JWKSet;
 
+import net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.claim.Metadata;
+
 /**
  * Entity Statement payload claims as defined by the OpenID Federation 1.0 Section 3.1. These claims MUST or MAY appear
  * in both Entity Configurations and Subordinate Statements.
@@ -47,7 +49,7 @@ public class EntityStatementPayload {
     @JsonProperty("jwks") private JWKSet jwkSet;
 
     /** A JSON object that declares roles that the Entity plays per its Entity Types. */
-    @JsonProperty("metadata") private Map<String, Map<String, Object>> metadata;
+    @JsonProperty("metadata") private Metadata metadata;
 
     /** The critical Claims that must be understood and processed. */
     @JsonProperty("crit") private List<String> critical;
@@ -150,17 +152,17 @@ public class EntityStatementPayload {
      * 
      * @return metadata
      */
-    public Map<String, Map<String, Object>> getMetadata() {
+    public Metadata getMetadata() {
         return metadata;
     }
 
     /**
      * Set the metadata.
      * 
-     * @param map metadata
+     * @param data metadata
      */
-    public void setMetadata(final Map<String, Map<String, Object>> map) {
-        metadata = map;
+    public void setMetadata(final Metadata data) {
+        metadata = data;
     }
 
     /**
diff --git a/idp-oidfed-op-api/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/claim/Metadata.java b/idp-oidfed-op-api/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/claim/Metadata.java
new file mode 100644
index 0000000..01977f1
--- /dev/null
+++ b/idp-oidfed-op-api/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/claim/Metadata.java
@@ -0,0 +1,267 @@
+/*
+ * 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.claim;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import com.fasterxml.jackson.annotation.JsonAnyGetter;
+import com.fasterxml.jackson.annotation.JsonAnySetter;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.google.common.base.MoreObjects;
+
+import net.shibboleth.shared.collection.CollectionSupport;
+
+/**
+ * Metadata claim as defined by the OpenID Federation 1.0 Section 5.
+ */
+public class Metadata {
+
+    /** Federation entity metadata. */
+    @JsonProperty("federation_entity") private Map<String,Object> federationEntityMetadata;
+
+    /** OpenID Connect Relying Party metadata. */
+    @JsonProperty("openid_relying_party") private Map<String,Object> openidRelyingPartyMetadata;
+
+    /** OpenID Connect OpenID Provider metadata. */
+    @JsonProperty("openid_provider") private Map<String,Object> openidProviderMetadata;
+
+    /** OAuth Authorization Server metadata. */
+    @JsonProperty("oauth_authorization_server") private Map<String,Object> oauthAuthorizationServerMetadata;
+
+    /** OAuth Client metadata. */
+    @JsonProperty("oauth_client") private Map<String,Object> oauthClientMetadata;
+
+    /** OAuth Protected Resource metadata. */
+    @JsonProperty("oauth_resource") private Map<String,Object> oauthResourceMetadata;
+
+    /** The map of any other claims not directly mapped. */
+    private final Map<String, Map<String, Object>> customClaims = new HashMap<>();
+
+    /**
+     * Constructor.
+     */
+    public Metadata() {
+        // no op
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param allClaims claims used for populating this object
+     */
+    public Metadata(@Nonnull final Map<String, Map<String, Object>> allClaims) {
+        final Map<String,Map<String,Object>> input = new HashMap<>(allClaims);
+        if (allClaims.containsKey("federation_entity")) {
+            federationEntityMetadata = allClaims.get("federation_entity");
+            input.remove("federation_entity");
+        }
+        if (allClaims.containsKey("openid_relying_party")) {
+            openidRelyingPartyMetadata = allClaims.get("openid_relying_party");
+            input.remove("openid_relying_party");
+        }
+        if (allClaims.containsKey("openid_provider")) {
+            openidProviderMetadata = allClaims.get("openid_provider");
+            input.remove("openid_provider");
+        }
+        if (allClaims.containsKey("oauth_authorization_server")) {
+            oauthAuthorizationServerMetadata = allClaims.get("oauth_authorization_server");
+            input.remove("oauth_authorization_server");
+        }
+        if (allClaims.containsKey("oauth_client")) {
+            oauthClientMetadata = allClaims.get("oauth_client");
+            input.remove("oauth_client");
+        }
+        if (allClaims.containsKey("oauth_resource")) {
+            oauthResourceMetadata = allClaims.get("oauth_resource");
+            input.remove("oauth_resource");
+        }
+        customClaims.putAll(input);
+    }
+
+    /**
+     * Get the federation entity metadata.
+     * 
+     * @return federation entity metadata
+     */
+    @Nullable public Map<String,Object> getFederationEntityMetadata() {
+        return federationEntityMetadata;
+    }
+
+    /**
+     * Set the federation entity metadata.
+     * 
+     * @param metadata federation entity metadata
+     */
+    public void setFederationEntityMetadata(@Nullable final Map<String,Object> metadata) {
+        federationEntityMetadata = metadata;
+    }
+
+    /**
+     * Get the OpenID Connect Relying Party metadata.
+     * 
+     * @return OIDC RP metadata
+     */
+    @Nullable public Map<String,Object> getOpenidRelyingPartyMetadata() {
+        return openidRelyingPartyMetadata;
+    }
+
+    /**
+     * Set the OpenID Connect Relying Party metadata.
+     * 
+     * @param metadata OIDC RP metadata
+     */
+    public void setOpenidRelyingPartyMetadata(@Nullable final Map<String,Object> metadata) {
+        openidRelyingPartyMetadata = metadata;
+    }
+
+    /**
+     * Get the OpenID Connect OpenID Provider metadata.
+     * 
+     * @return OIDC OP metadata
+     */
+    @Nullable public Map<String,Object> getOpenidProviderMetadata() {
+        return openidProviderMetadata;
+    }
+
+    /**
+     * Set the OpenID Connect OpenID Provider metadata.
+     * 
+     * @param metadata OIDC OP metadata
+     */
+    public void setOpenidProviderMetadata(@Nullable final Map<String,Object> metadata) {
+        openidProviderMetadata = metadata;
+    }
+
+    /**
+     * Get the OAuth Authorization Server metadata.
+     * 
+     * @return OAuth AS metadata
+     */
+    @Nullable public Map<String,Object> getOauthAuthorizationServerMetadata() {
+        return oauthAuthorizationServerMetadata;
+    }
+
+    /**
+     * Set the OAuth Authorization Server metadata.
+     * 
+     * @param metadata OAuth AS metadata
+     */
+    public void setOauthAuthorizationServerMetadata(@Nullable final Map<String,Object> metadata) {
+        oauthAuthorizationServerMetadata = metadata;
+    }
+
+    /**
+     * Get the OAuth Client metadata.
+     * 
+     * @return OAuth client metadata
+     */
+    @Nullable public Map<String,Object> getOauthClientMetadata() {
+        return oauthClientMetadata;
+    }
+
+    /**
+     * Set the OAuth Client metadata.
+     * 
+     * @param metadata OAuth client metadata
+     */
+    public void setOauthClientMetadata(@Nullable final Map<String,Object> metadata) {
+        oauthClientMetadata = metadata;
+    }
+
+    /**
+     * Get the OAuth Protected Resource metadata.
+     * 
+     * @return OAuth protected resource metadata
+     */
+    @Nullable public Map<String,Object> getOauthResourceMetadata() {
+        return oauthClientMetadata;
+    }
+
+    /**
+     * Set the OAuth Protected Resource metadata.
+     * 
+     * @param metadata OAuth protected resource metadata
+     */
+    public void setOauthResourceMetadata(@Nullable final Map<String,Object> metadata) {
+        oauthClientMetadata = metadata;
+    }
+
+    /**
+     * Get the map of custom claims.
+     * 
+     * @return The map of any other claims not directly mapped.
+     */
+    @JsonAnyGetter
+    public Map<String,Map<String, Object>> getCustomClaims() {
+        return customClaims;
+    }
+
+    /**
+     * Add a custom claim to the map of custom claims.
+     * 
+     * @param name The name of the custom claim.
+     * @param value The value of the custom claim.
+     */
+    @JsonAnySetter
+    public void setCustomClaims(final String name, final Map<String,Object> value) {
+        customClaims.put(name, value);
+    }
+
+    /**
+     * Get all claims (standard and custom) in a map keyed by entity types.
+     * 
+     * @return all claims
+     */
+    @Nonnull public Map<String,Map<String,Object>> getAllClaims() {
+        final Map<String,Map<String,Object>> claims = new HashMap<>();
+        if (federationEntityMetadata != null) {
+            claims.put("federation_entity", federationEntityMetadata);
+        }
+        if (openidRelyingPartyMetadata != null) {
+            claims.put("openid_relying_party", openidRelyingPartyMetadata);
+        }
+        if (openidProviderMetadata != null) {
+            claims.put("openid_provider", openidProviderMetadata);
+        }
+        if (oauthAuthorizationServerMetadata != null) {
+            claims.put("oauth_authorization_server", oauthAuthorizationServerMetadata);
+        }
+        if (oauthClientMetadata != null) {
+            claims.put("oauth_client", oauthClientMetadata);
+        }
+        if (oauthResourceMetadata != null) {
+            claims.put("oauth_resource", oauthClientMetadata);
+        }
+        claims.putAll(getCustomClaims());
+        return CollectionSupport.copyToMap(claims);
+    }
+    
+    /** {@inheritDoc} */
+    @Override public String toString() {
+        return MoreObjects.toStringHelper(this)
+                .add("federationEntityMetadata", getFederationEntityMetadata())
+                .add("openidRelyingPartyMetadata", getOpenidRelyingPartyMetadata())
+                .add("openidProviderMetadata", getOpenidProviderMetadata())
+                .add("oauthAuthorizationServerMetadata", getOauthAuthorizationServerMetadata())
+                .add("oauthClientMetadata", getOauthClientMetadata())
+                .add("oauthResourceMetadata", getOauthResourceMetadata())
+                .add("customClaims", getCustomClaims()).toString();
+    }
+
+}
diff --git a/idp-oidfed-op-api/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/context/RelyingPartyTrustChainContext.java b/idp-oidfed-op-api/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/context/RelyingPartyTrustChainContext.java
index c4b1b16..a272a06 100644
--- a/idp-oidfed-op-api/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/context/RelyingPartyTrustChainContext.java
+++ b/idp-oidfed-op-api/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/context/RelyingPartyTrustChainContext.java
@@ -26,6 +26,7 @@ import org.opensaml.messaging.context.BaseContext;
 import com.nimbusds.jwt.SignedJWT;
 
 import net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.EntityStatement;
+import net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.claim.Metadata;
 import net.shibboleth.idp.plugin.oidc.op.oidfed.profile.TrustedRemoteResolverEntity;
 import net.shibboleth.shared.collection.Pair;
 
@@ -38,10 +39,10 @@ public final class RelyingPartyTrustChainContext extends BaseContext {
     @Nullable private List<List<EntityStatement>> resolvedTrustChains;
 
     /** Policy-compliant trust chains for the relying party. */
-    @Nullable private List<Pair<List<EntityStatement>,Map<String,Map<String,Object>>>> policyCompliantTrustChains;
+    @Nullable private List<Pair<List<EntityStatement>,Metadata>> policyCompliantTrustChains;
 
     /** Selected trust chain for the relying party. */
-    @Nullable private Pair<List<EntityStatement>,Map<String,Map<String,Object>>> selectedTrustChain;
+    @Nullable private Pair<List<EntityStatement>,Metadata> selectedTrustChain;
 
     /** Expiration instant for the selected metadata. */
     @Nullable private Instant selectedMetadataExpiration;
@@ -86,7 +87,7 @@ public final class RelyingPartyTrustChainContext extends BaseContext {
      * 
      * @return the trust chains
      */
-    @Nullable public List<Pair<List<EntityStatement>,Map<String,Map<String,Object>>>> getPolicyCompliantTrustChains() {
+    @Nullable public List<Pair<List<EntityStatement>,Metadata>> getPolicyCompliantTrustChains() {
         return policyCompliantTrustChains;
     }
 
@@ -98,7 +99,7 @@ public final class RelyingPartyTrustChainContext extends BaseContext {
      * @return this context
      */
     @Nonnull public RelyingPartyTrustChainContext setPolicyCompliantTrustChains(
-            @Nullable final List<Pair<List<EntityStatement>,Map<String,Map<String,Object>>>> chains) {
+            @Nullable final List<Pair<List<EntityStatement>,Metadata>> chains) {
         policyCompliantTrustChains = chains;
         return this;
     }
@@ -108,7 +109,7 @@ public final class RelyingPartyTrustChainContext extends BaseContext {
      * 
      * @return the trust chain
      */
-    @Nullable public Pair<List<EntityStatement>,Map<String,Map<String,Object>>> getSelectedTrustChain() {
+    @Nullable public Pair<List<EntityStatement>,Metadata> getSelectedTrustChain() {
         return selectedTrustChain;
     }
 
@@ -120,7 +121,7 @@ public final class RelyingPartyTrustChainContext extends BaseContext {
      * @return this context
      */
     @Nonnull public RelyingPartyTrustChainContext setSelectedTrustChains(
-            @Nullable final Pair<List<EntityStatement>,Map<String,Map<String,Object>>> chain) {
+            @Nullable final Pair<List<EntityStatement>,Metadata> chain) {
         selectedTrustChain = chain;
         return this;
     }
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/cache/DefaultCombinedMetadataFromTrustChainLookupStrategy.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/cache/DefaultCombinedMetadataFromTrustChainLookupStrategy.java
index bff193a..fce60f3 100644
--- a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/cache/DefaultCombinedMetadataFromTrustChainLookupStrategy.java
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/cache/DefaultCombinedMetadataFromTrustChainLookupStrategy.java
@@ -50,9 +50,11 @@ public class DefaultCombinedMetadataFromTrustChainLookupStrategy extends Abstrac
             return null;
         }
         final Map<String,Map<String,Object>> configurationMetadata =
-                chain.get(0).getParsedPayload().getMetadata();
+                Optional.ofNullable(chain.get(0).getParsedPayload().getMetadata())
+                .map(metadata -> metadata.getAllClaims()).orElse(null);
         final Map<String,Map<String,Object>> subordinateMetadata =
-                chain.get(1).getParsedPayload().getMetadata();
+                Optional.ofNullable(chain.get(1).getParsedPayload().getMetadata())
+                .map(metadata -> metadata.getAllClaims()).orElse(null);
 
         if (configurationMetadata == null || configurationMetadata.isEmpty()) {
             log.error("Entity configuration for {} doesn't contain metadata", chain.get(0).getSubject());
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/cache/remote/subordinate/DefaultSubordinateStatementFetchingStrategy.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/cache/remote/subordinate/DefaultSubordinateStatementFetchingStrategy.java
index 34cb673..8182489 100644
--- a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/cache/remote/subordinate/DefaultSubordinateStatementFetchingStrategy.java
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/cache/remote/subordinate/DefaultSubordinateStatementFetchingStrategy.java
@@ -138,7 +138,7 @@ public class DefaultSubordinateStatementFetchingStrategy
         }
         final Map<String, Object> federationEntity =
                 Optional.ofNullable(entityConfiguration.getParsedPayload().getMetadata())
-                .map(metadata -> metadata.get("federation_entity"))
+                .map(metadata -> metadata.getFederationEntityMetadata())
                 .orElse(null);
         if (federationEntity == null) {
             log.error("TODO");
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/constraints/impl/DefaultAllowedEntityTypesConstraint.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/constraints/impl/DefaultAllowedEntityTypesConstraint.java
index 1215d54..ac20c9d 100644
--- a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/constraints/impl/DefaultAllowedEntityTypesConstraint.java
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/constraints/impl/DefaultAllowedEntityTypesConstraint.java
@@ -16,7 +16,6 @@ package net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.constraints.impl;
 
 import java.util.ArrayList;
 import java.util.List;
-import java.util.Map;
 import java.util.Optional;
 
 import javax.annotation.Nonnull;
@@ -27,8 +26,8 @@ import org.slf4j.Logger;
 import com.fasterxml.jackson.databind.ObjectMapper;
 
 import net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.EntityStatement;
+import net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.claim.Metadata;
 import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
-import net.shibboleth.shared.collection.CollectionSupport;
 import net.shibboleth.shared.component.ComponentInitializationException;
 import net.shibboleth.shared.logic.Constraint;
 import net.shibboleth.shared.logic.ConstraintViolationException;
@@ -90,16 +89,18 @@ public class DefaultAllowedEntityTypesConstraint extends AbstractFederationPolic
         log.trace("Allowed entity types: {}", allowedTypes);
         for (final EntityStatement entityStatement : trustChain) {
             assert entityStatement != null;
-            final Map<String, Map<String,Object>> metadata =
+            final Metadata metadata =
                     Optional.ofNullable(entityStatement.getParsedPayload().getMetadata())
-                    .orElse(CollectionSupport.emptyMap());
-            for (final String entityType : metadata.keySet()) {
-                if (!allowedTypes.contains(entityType)) {
-                    log.warn("The entity type {} is not allowed in entity statement {}", entityType,
-                            entityStatement.getSubject());
-                    return false;
+                    .orElse(null);
+            if (metadata != null) {
+                for (final String entityType : metadata.getAllClaims().keySet()) {
+                    if (!allowedTypes.contains(entityType)) {
+                        log.warn("The entity type {} is not allowed in entity statement {}", entityType,
+                                entityStatement.getSubject());
+                        return false;
+                    }
+                    log.trace("The entity type {} is allowed for {}", entityType, entityStatement.getSubject());
                 }
-                log.trace("The entity type {} is allowed for {}", entityType, entityStatement.getSubject());
             }
         }
         return true;
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/util/EntityStatementHelper.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/util/EntityStatementHelper.java
index 8689c2b..475c65c 100644
--- a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/util/EntityStatementHelper.java
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/util/EntityStatementHelper.java
@@ -80,7 +80,7 @@ public class EntityStatementHelper {
             if (!result.isEmpty()) {
                 return Optional.ofNullable(result.get(0).getEntityStatement())
                         .map(statement -> statement.getParsedPayload().getMetadata())
-                        .map(metadata -> metadata.get("federation_entity"))
+                        .map(metadata -> metadata.getFederationEntityMetadata())
                         .map(map -> map.get(endpointId))
                         .filter(String.class::isInstance)
                         .map(String.class::cast)
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/AbstractTrustChainResolutionAction.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/AbstractTrustChainResolutionAction.java
index 18ce7a0..abb3986 100644
--- a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/AbstractTrustChainResolutionAction.java
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/AbstractTrustChainResolutionAction.java
@@ -32,6 +32,7 @@ import org.slf4j.Logger;
 
 import net.minidev.json.JSONObject;
 import net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.EntityStatement;
+import net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.claim.Metadata;
 import net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.policy.FederationMetadataPolicyHelper;
 import net.shibboleth.idp.plugin.oidc.op.oidfed.profile.context.RelyingPartyTrustChainContext;
 import net.shibboleth.idp.profile.AbstractProfileAction;
@@ -238,7 +239,7 @@ public class AbstractTrustChainResolutionAction extends AbstractProfileAction {
      * @return error event ID if metadata policy merging or enforcement failed, null otherwise
      */
     @Nullable protected String populatePolicyComplaintChains(@Nonnull final List<EntityStatement> chain,
-            @Nonnull List<Pair<List<EntityStatement>, Map<String,Map<String,Object>>>> policyCompliantChains) {
+            @Nonnull List<Pair<List<EntityStatement>, Metadata>> policyCompliantChains) {
         final Map<String,Map<String,Object>> metadata = getMetadataLookupStrategy().apply(chain);
         log.trace("{} Metadata resolved via lookup strategy: {}", getLogPrefix(), metadata);
         if (metadata != null) {
@@ -275,7 +276,7 @@ public class AbstractTrustChainResolutionAction extends AbstractProfileAction {
                             chain.get(0).getSubject(), entityType);
                 }
             }
-            policyCompliantChains.add(new Pair<>(chain, verifiedMetadata));
+            policyCompliantChains.add(new Pair<>(chain, new Metadata(verifiedMetadata)));
             log.debug("{} Policy-enforced metadata {}", getLogPrefix(), verifiedMetadata);
             return null;
         }
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/AddExtensionsToClientInformation.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/AddExtensionsToClientInformation.java
index f65565d..55cc8e5 100644
--- a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/AddExtensionsToClientInformation.java
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/AddExtensionsToClientInformation.java
@@ -33,6 +33,7 @@ import com.nimbusds.openid.connect.sdk.rp.OIDCClientInformation;
 
 import net.shibboleth.idp.plugin.oidc.op.messaging.context.OIDCClientRegistrationResponseContext;
 import net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.EntityStatement;
+import net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.claim.Metadata;
 import net.shibboleth.idp.plugin.oidc.op.oidfed.profile.context.RelyingPartyTrustChainContext;
 import net.shibboleth.idp.plugin.oidc.op.oidfed.support.ClientInformationExtensionSupport;
 import net.shibboleth.idp.profile.AbstractProfileAction;
@@ -63,7 +64,7 @@ public class AddExtensionsToClientInformation extends AbstractProfileAction {
     @NonnullBeforeExec private  RelyingPartyTrustChainContext trustChainContext;
 
     /** Selected trust chain to operate on. */
-    @NonnullBeforeExec private Pair<List<EntityStatement>, Map<String,Map<String,Object>>> selectedTrustChain;
+    @NonnullBeforeExec private Pair<List<EntityStatement>, Metadata> selectedTrustChain;
 
     /** Constructor. */
     public AddExtensionsToClientInformation() {
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/BuildResolveEntityResponse.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/BuildResolveEntityResponse.java
index 73f365a..8986555 100644
--- a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/BuildResolveEntityResponse.java
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/BuildResolveEntityResponse.java
@@ -38,6 +38,7 @@ import com.nimbusds.jwt.JWTClaimsSet;
 import com.nimbusds.jwt.SignedJWT;
 
 import net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.EntityStatement;
+import net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.claim.Metadata;
 import net.shibboleth.idp.plugin.oidc.op.oidfed.profile.context.RelyingPartyTrustChainContext;
 import net.shibboleth.idp.plugin.oidc.op.oidfed.profile.navigate.DefaultEntityTypesLookupFunction;
 import net.shibboleth.shared.annotation.constraint.NonnullBeforeExec;
@@ -116,14 +117,14 @@ public class BuildResolveEntityResponse extends AbstractBuildEntityStatementActi
     @Override
     protected boolean populateClaimsSetBuilder(@Nonnull final JWTClaimsSet.Builder builder,
             @Nonnull final ProfileRequestContext profileRequestContext) {
-        final Pair<List<EntityStatement>,Map<String,Map<String,Object>>> selectedTrustChain =
+        final Pair<List<EntityStatement>,Metadata> selectedTrustChain =
                 trustChainContext.getSelectedTrustChain();
         if (selectedTrustChain == null) {
             log.debug("{} No selected trust chain found form the context", getLogPrefix());
             ActionSupport.buildEvent(profileRequestContext, OidFederationEventIds.INVALID_METADATA);
             return false;                                    
         }
-        final Map<String,Map<String,Object>> metadata = selectedTrustChain.getSecond();
+        final Metadata metadata = selectedTrustChain.getSecond();
         if (metadata == null) {
             log.debug("{} No metadata set for the selected trust chain", getLogPrefix());
             ActionSupport.buildEvent(profileRequestContext, OidFederationEventIds.INVALID_METADATA);
@@ -132,7 +133,7 @@ public class BuildResolveEntityResponse extends AbstractBuildEntityStatementActi
         final List<String> entityTypes = entityTypesLookupStrategy.apply(profileRequestContext);
         log.trace("{} The following entity types were requested: {}", getLogPrefix(), entityTypes);
         if (entityTypes != null && !entityTypes.isEmpty()) {
-            final Map<String,Object> filteredMetadata = metadata.entrySet()
+            final Map<String,Object> filteredMetadata = metadata.getAllClaims().entrySet()
                     .stream()
                     .filter(entry -> entityTypes.contains(entry.getKey()))
                     .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/CallResolveEntityApi.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/CallResolveEntityApi.java
index 1347221..3cd4786 100644
--- a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/CallResolveEntityApi.java
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/CallResolveEntityApi.java
@@ -55,6 +55,7 @@ import net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.cache.remote.SubjectEnt
 import net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.cache.remote.resolver.RemoteResolveEntityCacheContainerIdentifier;
 import net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.cache.remote.resolver.RemoteResolveEntityCacheIdentifierCriterion;
 import net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.cache.remote.resolver.RemoteResolveEntityResponseContainer;
+import net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.claim.Metadata;
 import net.shibboleth.idp.plugin.oidc.op.oidfed.profile.TrustedRemoteResolverEntity;
 import net.shibboleth.idp.plugin.oidc.op.oidfed.profile.context.RelyingPartyTrustChainContext;
 import net.shibboleth.idp.plugin.oidc.op.oidfed.profile.navigate.DefaultPreSelectedTrustChainIDsLookupStrategy;
@@ -390,7 +391,7 @@ public class CallResolveEntityApi extends AbstractProfileAction {
             }
             final URI uri = Optional.ofNullable(configurationCacheResult.get(0).getEntityStatement())
                         .map(statement -> statement.getParsedPayload().getMetadata())
-                        .map(metadata -> metadata.get("federation_entity"))
+                        .map(metadata -> metadata.getFederationEntityMetadata())
                         .map(entityMetadata -> entityMetadata.get("federation_resolve_endpoint"))
                         .map(endpoint -> URI.create((String) endpoint))
                         .orElse(null);
@@ -418,9 +419,9 @@ public class CallResolveEntityApi extends AbstractProfileAction {
             if (cacheResult.get(0).getEntityStatement() instanceof ResolveEntityResponse successResponse
                     && successResponse.getParsedPayload() instanceof ResolveEntityResponsePayload payload) {
                 final List<String> rawTrustChain = payload.getTrustChain();
-                final Map<String, Map<String, Object>> metadata = payload.getMetadata();
+                final Metadata metadata = payload.getMetadata();
                 final List<Map<String,String>> rawTrustMarks = payload.getTrustMarks();
-                if (rawTrustChain == null || rawTrustChain.isEmpty() || metadata == null || metadata.isEmpty()) {
+                if (rawTrustChain == null || rawTrustChain.isEmpty() || metadata == null) {
                     log.warn("{} Could not parse mandatory parameters from the response from {}", getLogPrefix(),
                             trustedEntity);
                     continue;
@@ -445,7 +446,7 @@ public class CallResolveEntityApi extends AbstractProfileAction {
                             getLogPrefix());
                     continue;
                 }
-                final List<Pair<List<EntityStatement>, Map<String,Map<String,Object>>>> policyCompliantChains =
+                final List<Pair<List<EntityStatement>, Metadata>> policyCompliantChains =
                         new ArrayList<>();
                 policyCompliantChains.add(new Pair<>(chain, metadata));
                 trustChainContext.setPolicyCompliantTrustChains(policyCompliantChains);
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/ResolveTrustChains.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/ResolveTrustChains.java
index 5467f4d..6804d2f 100644
--- a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/ResolveTrustChains.java
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/ResolveTrustChains.java
@@ -19,7 +19,6 @@ import java.net.URISyntaxException;
 import java.net.URL;
 import java.util.ArrayList;
 import java.util.List;
-import java.util.Map;
 import java.util.Optional;
 import java.util.function.Function;
 import java.util.function.Predicate;
@@ -38,6 +37,7 @@ import net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.EntityStatement;
 import net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.cache.SubjectEntityIDCriterion;
 import net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.cache.remote.RemoteTrustChainsContainer;
 import net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.cache.remote.SubjectEntityStatementCriterion;
+import net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.claim.Metadata;
 import net.shibboleth.idp.plugin.oidc.op.oidfed.profile.context.RelyingPartyTrustChainContext;
 import net.shibboleth.idp.plugin.oidc.op.oidfed.profile.navigate.DefaultPreSelectedTrustChainIDsLookupStrategy;
 import net.shibboleth.idp.plugin.oidc.op.oidfed.profile.navigate.DefaultTrustChainIDsLookupStrategy;
@@ -237,7 +237,7 @@ public class ResolveTrustChains extends AbstractTrustChainResolutionAction {
         final RelyingPartyTrustChainContext trustChainContext =
                 getTrustChainContextCreationStrategy().apply(profileRequestContext);
         trustChainContext.setResolvedTrustChains(cacheResult.get(0).getTrustChains());
-        final List<Pair<List<EntityStatement>, Map<String,Map<String,Object>>>> policyCompliantChains =
+        final List<Pair<List<EntityStatement>, Metadata>> policyCompliantChains =
                 new ArrayList<>();
 
         String errorEventId = null;
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/ResolveTrustMarks.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/ResolveTrustMarks.java
index f975add..580a4df 100644
--- a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/ResolveTrustMarks.java
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/ResolveTrustMarks.java
@@ -44,6 +44,7 @@ import net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.cache.SubjectEntityIDCr
 import net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.cache.TrustMarkOwnersCriterion;
 import net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.cache.remote.RemoteTrustChainsContainer;
 import net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.cache.remote.SubjectEntityStatementCriterion;
+import net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.claim.Metadata;
 import net.shibboleth.idp.plugin.oidc.op.oidfed.profile.context.RelyingPartyTrustChainContext;
 import net.shibboleth.idp.profile.AbstractProfileAction;
 import net.shibboleth.oidc.jwt.claims.ClaimsValidator;
@@ -290,8 +291,7 @@ public class ResolveTrustMarks extends AbstractProfileAction {
             return false;
         }
 
-        final Pair<List<EntityStatement>, Map<String,Map<String,Object>>> selectedChain =
-                trustChainContext.getSelectedTrustChain();
+        final Pair<List<EntityStatement>, Metadata> selectedChain = trustChainContext.getSelectedTrustChain();
 
         if (selectedChain == null || selectedChain.getFirst() == null) {
             ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_MSG_CTX);
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/SelectTrustChain.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/SelectTrustChain.java
index 8a6a26e..015559e 100644
--- a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/SelectTrustChain.java
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/SelectTrustChain.java
@@ -28,6 +28,7 @@ import org.opensaml.profile.context.navigate.InboundMessageContextLookup;
 import org.slf4j.Logger;
 
 import net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.EntityStatement;
+import net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.claim.Metadata;
 import net.shibboleth.idp.plugin.oidc.op.oidfed.profile.context.RelyingPartyTrustChainContext;
 import net.shibboleth.idp.plugin.oidc.op.oidfed.profile.navigate.DefaultTrustChainSelectionStrategy;
 import net.shibboleth.idp.profile.AbstractProfileAction;
@@ -59,8 +60,7 @@ public class SelectTrustChain extends AbstractProfileAction {
 
     /** Strategy used to fetch the selected trust chain and metadata. */
     @NonnullAfterInit
-    private Function<ProfileRequestContext,Pair<List<EntityStatement>, Map<String,Map<String,Object>>>>
-        selectedTrustChainLookupStrategy;
+    private Function<ProfileRequestContext,Pair<List<EntityStatement>, Metadata>> selectedTrustChainLookupStrategy;
 
     /** Trust chain context to operate on. */
     @NonnullBeforeExec private RelyingPartyTrustChainContext trustChainContext;
@@ -112,7 +112,7 @@ public class SelectTrustChain extends AbstractProfileAction {
      * @param strategy lookup strategy
      */
     public void setSelectedTrustChainLookupStrategy(@Nonnull final
-            Function<ProfileRequestContext,Pair<List<EntityStatement>, Map<String,Map<String,Object>>>> strategy) {
+            Function<ProfileRequestContext,Pair<List<EntityStatement>, Metadata>> strategy) {
         checkSetterPreconditions();
         selectedTrustChainLookupStrategy =
                 Constraint.isNotNull(strategy, "SelectedTrustChainLookupStrategy cannot be null");
@@ -146,7 +146,7 @@ public class SelectTrustChain extends AbstractProfileAction {
     /** {@inheritDoc} */
     @Override
     protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
-        final Pair<List<EntityStatement>, Map<String,Map<String,Object>>> selectedChain =
+        final Pair<List<EntityStatement>, Metadata> selectedChain =
                 selectedTrustChainLookupStrategy.apply(profileRequestContext);
 
         if (selectedChain == null || selectedChain.getFirst() == null || selectedChain.getSecond() == null) {
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/StoreAutomaticRegistration.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/StoreAutomaticRegistration.java
index 40ae86a..afb65ce 100644
--- a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/StoreAutomaticRegistration.java
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/StoreAutomaticRegistration.java
@@ -16,7 +16,6 @@ package net.shibboleth.idp.plugin.oidc.op.oidfed.profile.impl;
 
 import java.time.Instant;
 import java.util.List;
-import java.util.Map;
 import java.util.function.Function;
 
 import javax.annotation.Nonnull;
@@ -33,6 +32,7 @@ import com.nimbusds.openid.connect.sdk.rp.OIDCClientInformation;
 import com.nimbusds.openid.connect.sdk.rp.OIDCClientMetadata;
 
 import net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.EntityStatement;
+import net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.claim.Metadata;
 import net.shibboleth.idp.plugin.oidc.op.oidfed.profile.context.RelyingPartyTrustChainContext;
 import net.shibboleth.idp.plugin.oidc.op.oidfed.profile.navigate.DefaultSelectedTrustChainMetadataLookupStrategy;
 import net.shibboleth.idp.profile.AbstractProfileAction;
@@ -155,8 +155,7 @@ public class StoreAutomaticRegistration extends AbstractProfileAction {
             return false;
         }
 
-        final Pair<List<EntityStatement>,Map<String,Map<String,Object>>> selectedTrustChain =
-                trustChainContext.getSelectedTrustChain();
+        final Pair<List<EntityStatement>,Metadata> selectedTrustChain = trustChainContext.getSelectedTrustChain();
         assert selectedTrustChain != null;
 
         clientInformation = new OIDCClientInformation(
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/ValidateAutomaticRegistrationProfileConfiguration.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/ValidateAutomaticRegistrationProfileConfiguration.java
index 262b4eb..17dfac5 100644
--- a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/ValidateAutomaticRegistrationProfileConfiguration.java
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/ValidateAutomaticRegistrationProfileConfiguration.java
@@ -34,6 +34,7 @@ import com.nimbusds.openid.connect.sdk.rp.OIDCClientInformation;
 import com.nimbusds.openid.connect.sdk.rp.OIDCClientMetadata;
 
 import net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.EntityStatement;
+import net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.claim.Metadata;
 import net.shibboleth.idp.plugin.oidc.op.oidfed.profile.config.navigate.LocalMetadataPolicyLookupFunction;
 import net.shibboleth.idp.plugin.oidc.op.oidfed.profile.config.navigate.MandatoryTrustMarksLookupFunction;
 import net.shibboleth.idp.plugin.oidc.op.oidfed.profile.context.RelyingPartyTrustChainContext;
@@ -89,7 +90,7 @@ public class ValidateAutomaticRegistrationProfileConfiguration extends AbstractP
     @NonnullBeforeExec private RelyingPartyTrustChainContext trustChainContext;
 
     /** Selected trust chain to operate on. */
-    @NonnullBeforeExec private Pair<List<EntityStatement>, Map<String,Map<String,Object>>> selectedTrustChain;
+    @NonnullBeforeExec private Pair<List<EntityStatement>, Metadata> selectedTrustChain;
 
     /**
      * Constructor.
@@ -213,7 +214,9 @@ public class ValidateAutomaticRegistrationProfileConfiguration extends AbstractP
                 ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_MSG_CTX);
                 return;
             }
-            selectedTrustChain.setSecond(Map.of("openid_relying_party", clientInformation.toJSONObject()));
+            final Metadata selectedMetadata = new Metadata();
+            selectedMetadata.setOpenidRelyingPartyMetadata(clientInformation.toJSONObject());
+            selectedTrustChain.setSecond(selectedMetadata);
         } else {
             clientInformation = new OIDCClientInformation(
                     new ClientID(selectedTrustChain.getFirst().get(0).getSubject()), metadata);
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/ValidateProvidedTrustChain.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/ValidateProvidedTrustChain.java
index e606bb0..39bc225 100644
--- a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/ValidateProvidedTrustChain.java
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/ValidateProvidedTrustChain.java
@@ -27,6 +27,7 @@ import org.opensaml.profile.context.ProfileRequestContext;
 import org.slf4j.Logger;
 
 import net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.EntityStatement;
+import net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.claim.Metadata;
 import net.shibboleth.idp.plugin.oidc.op.oidfed.profile.context.RelyingPartyTrustChainContext;
 import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
 import net.shibboleth.shared.annotation.constraint.NonnullBeforeExec;
@@ -124,7 +125,7 @@ public class ValidateProvidedTrustChain extends AbstractTrustChainResolutionActi
                 getTrustChainContextCreationStrategy().apply(profileRequestContext);
         assert trustChain != null;
         trustChainContext.setResolvedTrustChains(CollectionSupport.listOf(trustChain));
-        final List<Pair<List<EntityStatement>, Map<String,Map<String,Object>>>> policyCompliantChains =
+        final List<Pair<List<EntityStatement>, Metadata>> policyCompliantChains =
                 new ArrayList<>();
 
         final String errorEventId = populatePolicyComplaintChains(trustChain, policyCompliantChains);
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/ValidateSelectedTrustChain.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/ValidateSelectedTrustChain.java
index 04cc4ce..74ab28e 100644
--- a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/ValidateSelectedTrustChain.java
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/ValidateSelectedTrustChain.java
@@ -16,7 +16,6 @@ package net.shibboleth.idp.plugin.oidc.op.oidfed.profile.impl;
 
 import java.util.ArrayList;
 import java.util.List;
-import java.util.Map;
 import java.util.function.Function;
 
 import javax.annotation.Nonnull;
@@ -30,6 +29,7 @@ import net.shibboleth.idp.plugin.oidc.op.oidfed.messaging.impl.ResolveEntityRequ
 import net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.EntityStatement;
 import net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.cache.SubjectEntityIDCriterion;
 import net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.cache.remote.RemoteEntityConfigurationContainer;
+import net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.claim.Metadata;
 import net.shibboleth.idp.plugin.oidc.op.oidfed.profile.context.RelyingPartyTrustChainContext;
 import net.shibboleth.idp.profile.AbstractProfileAction;
 import net.shibboleth.oidc.metadata.cache.MetadataCache;
@@ -166,10 +166,10 @@ public class ValidateSelectedTrustChain extends AbstractProfileAction {
     protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
         final RelyingPartyTrustChainContext trustChainContext =
                 trustChainContextLookupStrategy.apply(profileRequestContext);
-        final Pair<List<EntityStatement>, Map<String,Map<String,Object>>>  selectedTrustChain =
+        final Pair<List<EntityStatement>, Metadata>  selectedTrustChain =
                 trustChainContext != null ? trustChainContext.getSelectedTrustChain() : null;
         if (selectedTrustChain == null || selectedTrustChain.getFirst() == null) {
-            final List<Pair<List<EntityStatement>,Map<String,Map<String,Object>>>> allChains =
+            final List<Pair<List<EntityStatement>,Metadata>> allChains =
                     trustChainContext != null ? trustChainContext.getPolicyCompliantTrustChains() : null;
             if (allChains == null || allChains.isEmpty()) {
                 if (isSubjectValid(validatedRequest.getSubject())) {
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/navigate/DefaultSelectedTrustChainMetadataLookupStrategy.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/navigate/DefaultSelectedTrustChainMetadataLookupStrategy.java
index 8740565..b3f2276 100644
--- a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/navigate/DefaultSelectedTrustChainMetadataLookupStrategy.java
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/navigate/DefaultSelectedTrustChainMetadataLookupStrategy.java
@@ -14,9 +14,7 @@
 
 package net.shibboleth.idp.plugin.oidc.op.oidfed.profile.navigate;
 
-import java.util.Map;
 import java.util.Optional;
-import java.util.stream.Collectors;
 
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
@@ -39,12 +37,7 @@ public class DefaultSelectedTrustChainMetadataLookupStrategy
     public OIDCClientMetadata doApply(@Nonnull final RelyingPartyTrustChainContext trustChainContext) {
         return Optional.ofNullable(trustChainContext.getSelectedTrustChain())
                 .map(pair -> pair.getSecond())
-                .map(map -> map.get("openid_relying_party"))
-                .filter(Map.class::isInstance)
-                .map(obj -> (Map<?,?>) obj)
-                .map(map -> map.entrySet().stream()
-                        .filter(e -> e.getKey() instanceof String && e.getValue() != null)
-                        .collect(Collectors.toMap(e -> (String) e.getKey(), e -> e.getValue())))
+                .map(map -> map.getOpenidRelyingPartyMetadata())
                 .map(JSONObject::new)
                 .map(json-> {
                     try {
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/navigate/DefaultTrustChainSelectionStrategy.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/navigate/DefaultTrustChainSelectionStrategy.java
index 5ac234f..ab21ccf 100644
--- a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/navigate/DefaultTrustChainSelectionStrategy.java
+++ b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/navigate/DefaultTrustChainSelectionStrategy.java
@@ -15,7 +15,6 @@
 package net.shibboleth.idp.plugin.oidc.op.oidfed.profile.navigate;
 
 import java.util.List;
-import java.util.Map;
 
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
@@ -23,6 +22,7 @@ import javax.annotation.Nullable;
 import org.slf4j.Logger;
 
 import net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.EntityStatement;
+import net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.claim.Metadata;
 import net.shibboleth.idp.plugin.oidc.op.oidfed.profile.context.RelyingPartyTrustChainContext;
 import net.shibboleth.shared.collection.Pair;
 import net.shibboleth.shared.primitive.LoggerFactory;
@@ -33,16 +33,16 @@ import net.shibboleth.shared.primitive.LoggerFactory;
  * {@link RelyingPartyTrustChainContext#getRejectedTrustChains()}.
  */
 public class DefaultTrustChainSelectionStrategy
-    extends AbstractTrustChainContextLookupFunction<Pair<List<EntityStatement>, Map<String,Map<String,Object>>>> {
+    extends AbstractTrustChainContextLookupFunction<Pair<List<EntityStatement>, Metadata>> {
 
     /** Class logger. */
     @Nonnull private Logger log = LoggerFactory.getLogger(DefaultTrustChainSelectionStrategy.class);
 
     /** {@inheritDoc} */
     @Override @Nullable
-    public Pair<List<EntityStatement>, Map<String,Map<String,Object>>> doApply(
+    public Pair<List<EntityStatement>, Metadata> doApply(
             @Nonnull final RelyingPartyTrustChainContext trustChainContext) {
-        final List<Pair<List<EntityStatement>, Map<String,Map<String,Object>>>> policyCompliantChains =
+        final List<Pair<List<EntityStatement>, Metadata>> policyCompliantChains =
                 trustChainContext.getPolicyCompliantTrustChains();
 
         if (policyCompliantChains == null || policyCompliantChains.isEmpty()) {

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


More information about the commits mailing list