[java-idp-oidc] branch dev/JOIDC-222 updated: JOIDC-222 - Support for OpenID Federation

Henri Mikkonen henri.mikkonen at iki.fi
Wed Aug 13 11:39:14 UTC 2025


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

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

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

The following commit(s) were added to refs/heads/dev/JOIDC-222 by this push:
     new f5f72d84 JOIDC-222 - Support for OpenID Federation
f5f72d84 is described below

commit f5f72d84e1e74d8aa6ab2e0d742c2d6b9d847f25
Author: Henri Mikkonen <henri.mikkonen at iki.fi>
AuthorDate: Wed Aug 13 14:38:52 2025 +0300

    JOIDC-222 - Support for OpenID Federation
    
    https://shibboleth.atlassian.net/browse/JOIDC-222
    
    Improved configuration of the contents of entity configuration
    - Not hardcoded to publish solely openid_provider anymore
    - Template can be customized via 'conf/oidfed/oidfed-entity-configuration-metadata.json' (example file included in the distribution package)
      - Filename can be customized via 'idp.oidfed.configuration.MetadataSkaletonFile' -property
    
    Moved local trust anchor file into conf/oidfed -directory
    - Default filename is '/conf/oidfed/oidfed-trust-anchors.json' (empty file included in the distribution package)
      - Filename can be customized via 'idp.oidfed.LocalTrustAnchorsFile' -property
---
 ...onfigurationMetadataSkeletonLookupStrategy.java | 84 ++++++++++++++++++++++
 .../profile/impl/BuildEntityConfiguration.java     | 10 +--
 .../profile/impl/EntityStatementContext.java       | 20 +++---
 .../impl/InitializeEntityStatementContext.java     | 65 +++++++++++++++--
 .../META-INF/net.shibboleth.idp/postconfig.xml     |  2 +-
 .../entity-configuration-beans.xml                 | 47 +++++++++++-
 .../oidfed-entity-configuration-metadata.json      |  7 ++
 .../oidc/op/conf/oidfed/oidfed-trust-anchors.json  |  2 +
 .../idp/plugin/oidc/op/module.properties           |  6 ++
 .../flow/oidfed/EntityConfigurationFlowTest.java   |  4 ++
 .../net/shibboleth/idp/module/conf/oidc.properties |  1 +
 .../conf/oidfed-entity-configuration-metadata.json |  7 ++
 .../conf/{ => oidfed}/oidfed-trust-anchors.json    |  0
 13 files changed, 232 insertions(+), 23 deletions(-)

diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultEntityConfigurationMetadataSkeletonLookupStrategy.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultEntityConfigurationMetadataSkeletonLookupStrategy.java
new file mode 100644
index 00000000..91d0dc14
--- /dev/null
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/metadata/DefaultEntityConfigurationMetadataSkeletonLookupStrategy.java
@@ -0,0 +1,84 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.idp.plugin.oidc.op.oidfed.metadata;
+
+import java.util.Map;
+import java.util.Optional;
+import java.util.function.Function;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.slf4j.Logger;
+
+import net.shibboleth.oidc.metadata.cache.MetadataCache;
+import net.shibboleth.oidc.metadata.cache.MetadataCacheException;
+import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
+import net.shibboleth.shared.annotation.constraint.ThreadSafeAfterInit;
+import net.shibboleth.shared.collection.CollectionSupport;
+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.resolver.CriteriaSet;
+
+/**
+ * Default strategy for fetching skeleton for entity configuration metadata via criteria.
+ */
+ at ThreadSafeAfterInit
+public class DefaultEntityConfigurationMetadataSkeletonLookupStrategy extends AbstractIdentifiableInitializableComponent
+        implements Function<CriteriaSet, Map<String,Map<String,Object>>> {
+
+    /** Class logger. */
+    @Nonnull
+    private Logger log = LoggerFactory.getLogger(DefaultEntityConfigurationMetadataSkeletonLookupStrategy.class);
+
+    /** Metadata cache providing metadata skeleton. */
+    @NonnullAfterInit private MetadataCache<Map<String,Map<String,Object>>> metadataSkeletonCache;
+
+    /**
+     * Set the cache providing metadata skeleton.
+     * 
+     * @param cache cache providing metadata skeleton
+     */
+    public void setMetadataSkeletonCache(@Nonnull final MetadataCache<Map<String,Map<String,Object>>> cache) {
+        checkSetterPreconditions();
+        metadataSkeletonCache = Constraint.isNotNull(cache, "Metadata skeleton cache cannot be null");
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    protected void doInitialize() throws ComponentInitializationException {
+        super.doInitialize();
+        if (metadataSkeletonCache == null) {
+            throw new ComponentInitializationException("Metadata skeleton cache cannot be null");
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override @Nullable
+    public Map<String,Map<String,Object>> apply(@Nullable final CriteriaSet criteria) {
+        checkComponentActive();
+        try {
+            return Optional.of(metadataSkeletonCache.get(criteria))
+                    .filter(result -> result.size() == 1)
+                    .map(result -> result.get(0))
+                    .orElse(CollectionSupport.emptyMap());
+        } catch (final MetadataCacheException e) {
+            log.error("Could not fetch metadata skeleton via metadata cache", e);
+        }
+        return CollectionSupport.emptyMap();
+    }
+}
diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/BuildEntityConfiguration.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/BuildEntityConfiguration.java
index 21a4dd2d..c58a301e 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/BuildEntityConfiguration.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/BuildEntityConfiguration.java
@@ -19,6 +19,7 @@ import java.time.Instant;
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
+import java.util.Map;
 import java.util.function.Function;
 
 import javax.annotation.Nonnull;
@@ -31,7 +32,6 @@ import org.slf4j.Logger;
 import com.nimbusds.jose.jwk.JWK;
 import com.nimbusds.jose.jwk.JWKSet;
 import com.nimbusds.jwt.JWTClaimsSet;
-import com.nimbusds.openid.connect.sdk.op.OIDCProviderMetadata;
 
 import net.shibboleth.idp.plugin.oidc.op.oidfed.profile.navigate.EntityStatementLifetimeLookupFunction;
 import net.shibboleth.idp.profile.IdPEventIds;
@@ -67,8 +67,8 @@ public class BuildEntityConfiguration extends AbstractBuildEntityStatementAction
     /** Strategy used to obtain the entity statement lifetime. */
     @Nonnull private Function<ProfileRequestContext,Duration> entityConfigurationLifetimeLookupStrategy;
 
-    /** OIDC provider metadata to publish. */
-    @NonnullBeforeExec private OIDCProviderMetadata metadata;
+    /** Metadata to publish. */
+    @NonnullBeforeExec private Map<String,Map<String,Object>> metadata;
 
     /** Constructor. */
     public BuildEntityConfiguration() {
@@ -96,7 +96,7 @@ public class BuildEntityConfiguration extends AbstractBuildEntityStatementAction
             return false;
         }
 
-        metadata = entityStatementCtx.getOPMetadata();
+        metadata = entityStatementCtx.getMetadata();
         if (metadata == null) {
             log.error("{} Could not resolve provider metadata", getLogPrefix());
             ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_PROFILE_CTX);
@@ -141,7 +141,7 @@ public class BuildEntityConfiguration extends AbstractBuildEntityStatementAction
 
         builder.expirationTime(Date.from(dateExp));
         builder.claim("jwks", new JWKSet(jwks).toJSONObject(true));
-        builder.claim("metadata", CollectionSupport.singletonMap("openid_provider", metadata.toJSONObject()));
+        builder.claim("metadata", CollectionSupport.copyToMap(metadata));
         return true;
    }
 
diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/EntityStatementContext.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/EntityStatementContext.java
index 7b6af76e..7eebe3ab 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/EntityStatementContext.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/EntityStatementContext.java
@@ -15,6 +15,7 @@
 package net.shibboleth.idp.plugin.oidc.op.oidfed.profile.impl;
 
 import java.time.Duration;
+import java.util.Map;
 
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
@@ -22,7 +23,6 @@ import javax.annotation.Nullable;
 import org.opensaml.messaging.context.BaseContext;
 
 import com.nimbusds.jwt.JWT;
-import com.nimbusds.openid.connect.sdk.op.OIDCProviderMetadata;
 
 /**
  * Subcontext carrying information used to produce entity statements.
@@ -31,8 +31,8 @@ import com.nimbusds.openid.connect.sdk.op.OIDCProviderMetadata;
  */
 public final class EntityStatementContext extends BaseContext {
 
-    /** OIDC provider metadata. */
-    @Nullable private OIDCProviderMetadata opMetadata;
+    /** Metadata. */
+    @Nullable private Map<String,Map<String,Object>> metadata;
 
     /** Lifetime of the statement. */
     @Nullable private Duration lifetime;
@@ -41,23 +41,23 @@ public final class EntityStatementContext extends BaseContext {
     @Nullable private JWT jwt;
 
     /**
-     * Get the OIDC provider metadata.
+     * Get the metadata.
      * 
      * @return the metadata
      */
-    @Nullable public OIDCProviderMetadata getOPMetadata() {
-        return opMetadata;
+    @Nullable public Map<String,Map<String,Object>> getMetadata() {
+        return metadata;
     }
 
     /**
-     * Set the OIDC provider metadata.
+     * Set the metadata.
      * 
-     * @param metadata the metadata
+     * @param map the metadata
      * 
      * @return this context
      */
-    @Nonnull public EntityStatementContext setOPMetadata(@Nullable final OIDCProviderMetadata metadata) {
-        opMetadata = metadata;
+    @Nonnull public EntityStatementContext setMetadata(@Nullable final Map<String,Map<String,Object>> map) {
+        metadata = map;
         return this;
     }
     
diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/InitializeEntityStatementContext.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/InitializeEntityStatementContext.java
index ec17c6eb..9433124b 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/InitializeEntityStatementContext.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/InitializeEntityStatementContext.java
@@ -14,10 +14,12 @@
 
 package net.shibboleth.idp.plugin.oidc.op.oidfed.profile.impl;
 
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Optional;
 import java.util.function.Function;
 
 import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
 
 import org.opensaml.profile.action.EventIds;
 import org.opensaml.profile.context.ProfileRequestContext;
@@ -29,9 +31,13 @@ import com.nimbusds.openid.connect.sdk.op.OIDCProviderMetadata;
 import net.shibboleth.idp.plugin.oidc.op.metadata.resolver.ProviderMetadataResolver;
 import net.shibboleth.idp.profile.AbstractProfileAction;
 import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
+import net.shibboleth.shared.annotation.constraint.NonnullBeforeExec;
+import net.shibboleth.shared.collection.CollectionSupport;
 import net.shibboleth.shared.component.ComponentInitializationException;
 import net.shibboleth.shared.logic.Constraint;
 import net.shibboleth.shared.primitive.LoggerFactory;
+import net.shibboleth.shared.primitive.NonnullSupplier;
+import net.shibboleth.shared.resolver.CriteriaSet;
 import net.shibboleth.shared.resolver.ResolverException;
 
 import org.opensaml.messaging.context.navigate.ChildContextLookup;
@@ -54,11 +60,18 @@ public class InitializeEntityStatementContext extends AbstractProfileAction {
     /** The resolver for the metadata that is being distributed. */
     @NonnullAfterInit private ProviderMetadataResolver metadataResolver;
 
+    /** Strategy used to locate skeleton for the metadata claim. */
+    @NonnullAfterInit
+    private Function<CriteriaSet,Map<String,Map<String,Object>>> metadataSkeletonLookupStrategy;
+
     /** Strategy used to create the subcontext to hold the statement. */
     @Nonnull private Function<ProfileRequestContext,EntityStatementContext> entityStatementContextCreationStrategy;
 
     /** Entity statement context. */
-    @Nullable private EntityStatementContext entityStatementCtx;
+    @NonnullBeforeExec private EntityStatementContext entityStatementCtx;
+
+    /** Metadata skeleton. */
+    @NonnullBeforeExec private Map<String,Map<String,Object>> metadataSkeleton;
 
     /** Constructor. */
     public InitializeEntityStatementContext() {
@@ -78,6 +91,19 @@ public class InitializeEntityStatementContext extends AbstractProfileAction {
         metadataResolver = Constraint.isNotNull(resolver, "The metadata resolver cannot be null!");
     }
 
+    /**
+     * Set the strategy used to locate skeleton for the metadata claim.
+     * 
+     * @param strategy lookup strategy
+     */
+    public void setMetadataSkeletonLookupStrategy(
+            @Nonnull final Function<CriteriaSet,Map<String,Map<String,Object>>> strategy) {
+        checkSetterPreconditions();
+        
+        metadataSkeletonLookupStrategy =
+                Constraint.isNotNull(strategy, "MetadataSkeletonLookupStrategy cannot be null");
+    }
+
     /**
      * Set the strategy used to create the {@link EntityStatementContext} to use.
      * 
@@ -85,7 +111,7 @@ public class InitializeEntityStatementContext extends AbstractProfileAction {
      */
     public void setEntityStatementContextCreationStrategy(
             @Nonnull final Function<ProfileRequestContext,EntityStatementContext> strategy) {
-        ifInitializedThrowUnmodifiabledComponentException();
+        checkSetterPreconditions();
         
         entityStatementContextCreationStrategy =
                 Constraint.isNotNull(strategy, "EntityStatementContext creation strategy cannot be null");
@@ -99,6 +125,9 @@ public class InitializeEntityStatementContext extends AbstractProfileAction {
         if (metadataResolver == null) {
             throw new ComponentInitializationException("The metadata resolver cannot be null!");
         }
+        if (metadataSkeletonLookupStrategy == null) {
+            throw new ComponentInitializationException("MetadataSkeletonLookupStrategy cannot be null");
+        }
     }
 
  // Checkstyle: CyclomaticComplexity|MethodLength OFF
@@ -116,6 +145,9 @@ public class InitializeEntityStatementContext extends AbstractProfileAction {
             return false;
         }
 
+        metadataSkeleton = Optional.ofNullable(metadataSkeletonLookupStrategy.apply(new CriteriaSet()))
+                .orElseGet(NonnullSupplier.of(CollectionSupport.emptyMap()));
+
         return true;
     }
 
@@ -136,9 +168,30 @@ public class InitializeEntityStatementContext extends AbstractProfileAction {
             ActionSupport.buildEvent(profileRequestContext, EventIds.IO_ERROR);
             return;
         }
+        //TODO more types? (esp. OAuth2 AS)
+        entityStatementCtx.setMetadata(mergeMetadata(metadataSkeleton, "openid_provider", metadata.toJSONObject()));
+    }
 
-        assert entityStatementCtx != null;
-        entityStatementCtx.setOPMetadata(metadata);
+    /**
+     * Merge the given key and input to the given metadata skeleton. The input will overwrite the possibly existing
+     * values for the same key.
+     * 
+     * @param metadata the metadata skeleton
+     * @param key the key in the skeleton to be merged
+     * @param input the data to be merged (overwrites possibly already existing attributes)
+     * @return the merged metadata
+     */
+    protected Map<String,Map<String,Object>> mergeMetadata(@Nonnull final Map<String,Map<String,Object>> metadata,
+            @Nonnull final String key, @Nonnull final Map<String,Object> input) {
+        final Map<String,Map<String,Object>> result = new HashMap<>(metadata);
+        final Map<String,Object> base = metadata.get(key);
+        if (base != null) {
+            final Map<String,Object> values = new HashMap<>(base);
+            values.putAll(input);
+            result.put(key, values);
+        } else {
+            result.put(key, input);
+        }
+        return result;
     }
-        
 }
\ No newline at end of file
diff --git a/idp-oidc-extension-impl/src/main/resources/META-INF/net.shibboleth.idp/postconfig.xml b/idp-oidc-extension-impl/src/main/resources/META-INF/net.shibboleth.idp/postconfig.xml
index 8ada0f86..cb8e1ddc 100644
--- a/idp-oidc-extension-impl/src/main/resources/META-INF/net.shibboleth.idp/postconfig.xml
+++ b/idp-oidc-extension-impl/src/main/resources/META-INF/net.shibboleth.idp/postconfig.xml
@@ -1196,7 +1196,7 @@
     </util:map>
 
     <bean id="shibboleth.oidfed.DefaultLocalTrustAnchorsFilename" class="java.lang.String" factory-method="valueOf">
-        <constructor-arg value="%{idp.oidfed.DefaultLocalTrustAnchorsFile:%{idp.home}/conf/oidfed-trust-anchors.json}" />
+        <constructor-arg value="%{idp.oidfed.LocalTrustAnchorsFile:%{idp.home}/conf/oidfed/oidfed-trust-anchors.json}" />
     </bean>
 
     <bean id="shibboleth.oidfed.LocalTrustAnchorsMetadataCacheBuilderSpec"
diff --git a/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidfed/entity-configuration/entity-configuration-beans.xml b/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidfed/entity-configuration/entity-configuration-beans.xml
index 080dfc5a..585c079c 100644
--- a/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidfed/entity-configuration/entity-configuration-beans.xml
+++ b/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidfed/entity-configuration/entity-configuration-beans.xml
@@ -50,7 +50,12 @@
 
     <bean id="InitializeEntityStatementContext"
         class="net.shibboleth.idp.plugin.oidc.op.oidfed.profile.impl.InitializeEntityStatementContext"
-        p:metadataResolver-ref="#{'%{idp.oidfed.configuration.resolver:shibboleth.oidfed.DefaultOpenIdConfigurationResolver}'.trim()}"/>
+        p:metadataResolver-ref="#{'%{idp.oidfed.configuration.resolver:shibboleth.oidfed.DefaultOpenIdConfigurationResolver}'.trim()}"
+        p:metadataSkeletonLookupStrategy-ref="#{'%{idp.oidfed.configuration.EntityConfigurationMetadataSkeletonLookupStrategy:DefaultEntityConfigurationMetadataSkeletonLookupStrategy}'.trim()}"/>
+
+    <bean id="DefaultEntityConfigurationMetadataSkeletonLookupStrategy"
+        class="net.shibboleth.idp.plugin.oidc.op.oidfed.metadata.DefaultEntityConfigurationMetadataSkeletonLookupStrategy"
+        p:metadataSkeletonCache-ref="shibboleth.oidfed.EntityConfigurationMetadataSkeletonMetadataCache"/>
 
     <bean id="PopulateEntityStatementSignatureSigningParameters"
         class="net.shibboleth.oidc.profile.impl.PopulateJWTSignatureSigningParameters" scope="prototype"
@@ -117,4 +122,44 @@
         scope="prototype" p:responseCache-ref="shibboleth.oidfed.EntityConfigurationResponseMetadataCache">
     </bean>
 
+    <bean id="shibboleth.oidfed.EntityConfigurationMetadataSkeletonMetadataCache" parent="shibboleth.oidc.CacheBuilder">
+        <constructor-arg>
+            <bean p:cacheId="DefaultEntityConfigurationMetadataSkeletonMetadataCache"
+                parent="shibboleth.oidfed.EntityConfigurationMetadataSkeletonMetadataCacheBuilderSpec"/>
+        </constructor-arg>
+    </bean>
+
+    <bean id="shibboleth.oidfed.EntityConfigurationMetadataSkeletonMetadataCacheBuilderSpec"
+        class="net.shibboleth.oidc.metadata.cache.impl.BatchMetadataCacheBuilderSpec"
+        p:metadataValidPredicate-ref="shibboleth.Conditions.TRUE">
+        <property name="criteriaToIdentifierStrategy">
+            <bean parent="shibboleth.Functions.Constant" c:target-ref="shibboleth.oidc.issuer" />
+        </property>
+        <property name="identifierExtractionStrategy">
+            <bean parent="shibboleth.Functions.Constant" c:target-ref="shibboleth.oidc.issuer" />
+        </property>
+        <property name="loadingStrategy">
+            <bean class="net.shibboleth.oidc.metadata.cache.impl.DefaultResourceLoadingStrategy">
+                <constructor-arg name="metadata">
+                    <bean class="org.springframework.core.io.Resource"
+                        factory-bean="PreferFileSystemResourceLoader" factory-method="getResource">
+                        <constructor-arg>
+                            <bean class="java.lang.String" factory-method="valueOf">
+                                <constructor-arg value="%{idp.oidfed.configuration.MetadataSkaletonFile:%{idp.home}/conf/oidfed/oidfed-entity-configuration-metadata.json}" />
+                            </bean>
+                        </constructor-arg>
+                    </bean>
+                </constructor-arg>
+            </bean>
+        </property>
+        <property name="parsingStrategy">
+            <bean class="net.shibboleth.oidc.metadata.cache.impl.DefaultJSONMapParsingStrategy"
+                c:valueClass="java.util.Map"/>
+        </property>
+        <property name="sourceMetadataExpiryStrategy">
+            <bean class="net.shibboleth.oidc.metadata.cache.impl.DefaultSourceMetadataExpirationTimeStrategy"
+                c:duration="%{idp.oidfed.configuration.MetadataSkaletonCacheLifetime:PT10M}"/>
+        </property>
+    </bean>
+
 </beans>
diff --git a/idp-oidc-extension-impl/src/main/resources/net/shibboleth/idp/plugin/oidc/op/conf/oidfed/oidfed-entity-configuration-metadata.json b/idp-oidc-extension-impl/src/main/resources/net/shibboleth/idp/plugin/oidc/op/conf/oidfed/oidfed-entity-configuration-metadata.json
new file mode 100644
index 00000000..42045470
--- /dev/null
+++ b/idp-oidc-extension-impl/src/main/resources/net/shibboleth/idp/plugin/oidc/op/conf/oidfed/oidfed-entity-configuration-metadata.json
@@ -0,0 +1,7 @@
+{
+    "openid_provider": {
+        "organization_name" : "Example organization",
+        "organization_uri" : "https://org.example.org",
+        "contacts" : [ "contact at example.org" ]
+    }
+}
\ No newline at end of file
diff --git a/idp-oidc-extension-impl/src/main/resources/net/shibboleth/idp/plugin/oidc/op/conf/oidfed/oidfed-trust-anchors.json b/idp-oidc-extension-impl/src/main/resources/net/shibboleth/idp/plugin/oidc/op/conf/oidfed/oidfed-trust-anchors.json
new file mode 100644
index 00000000..7a73a41b
--- /dev/null
+++ b/idp-oidc-extension-impl/src/main/resources/net/shibboleth/idp/plugin/oidc/op/conf/oidfed/oidfed-trust-anchors.json
@@ -0,0 +1,2 @@
+{
+}
\ No newline at end of file
diff --git a/idp-oidc-extension-impl/src/main/resources/net/shibboleth/idp/plugin/oidc/op/module.properties b/idp-oidc-extension-impl/src/main/resources/net/shibboleth/idp/plugin/oidc/op/module.properties
index 18d5e8ae..d0043855 100644
--- a/idp-oidc-extension-impl/src/main/resources/net/shibboleth/idp/plugin/oidc/op/module.properties
+++ b/idp-oidc-extension-impl/src/main/resources/net/shibboleth/idp/plugin/oidc/op/module.properties
@@ -79,4 +79,10 @@ idp.oidc.OP.6.15.nonwindows = false
 idp.oidc.OP.6.16.src = /net/shibboleth/idp/plugin/oidc/op/conf/oidc-unregistered-client-policy.json
 idp.oidc.OP.6.16.dest = conf/oidc-unregistered-client-policy.json
 
+idp.oidc.OP.6.17.src = /net/shibboleth/idp/plugin/oidc/op/conf/oidfed/oidfed-trust-anchors.json
+idp.oidc.OP.6.17.dest = conf/oidfed/oidfed-trust-anchors.json
+
+idp.oidc.OP.6.18.src = /net/shibboleth/idp/plugin/oidc/op/conf/oidfed/oidfed-entity-configuration-metadata.json
+idp.oidc.OP.6.18.dest = conf/oidfed/oidfed-entity-configuration-metadata.json
+
 idp.oidc.OP.6.postenable = See documentation for additional instructions to enable the OP module.
diff --git a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/oidfed/EntityConfigurationFlowTest.java b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/oidfed/EntityConfigurationFlowTest.java
index 1ddd2cd2..f079c81d 100644
--- a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/oidfed/EntityConfigurationFlowTest.java
+++ b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/oidfed/EntityConfigurationFlowTest.java
@@ -31,6 +31,7 @@ import com.nimbusds.oauth2.sdk.ParseException;
 import com.nimbusds.oauth2.sdk.Response;
 import com.nimbusds.oauth2.sdk.id.Issuer;
 import com.nimbusds.openid.connect.sdk.federation.entities.EntityStatement;
+import com.nimbusds.openid.connect.sdk.federation.entities.FederationEntityMetadata;
 import com.nimbusds.openid.connect.sdk.federation.registration.ClientRegistrationType;
 import com.nimbusds.openid.connect.sdk.op.OIDCProviderMetadata;
 
@@ -99,6 +100,9 @@ public class EntityConfigurationFlowTest extends AbstractFederationFlowTest {
         } catch (URISyntaxException e) {
             Assert.fail("Could not build URI", e);
         }
+        final FederationEntityMetadata entityMetadata = entityStatement.getClaimsSet().getFederationEntityMetadata();
+        Assert.assertEquals(entityMetadata.getOrganizationName(), "Example organization");
+        Assert.assertEquals(entityMetadata.getContacts(), List.of("contact at example.org"));
     }
 
     protected boolean containsAll(Collection<? extends Algorithm> algs, Collection<String> strings) {
diff --git a/idp-oidc-extension-impl/src/test/resources/net/shibboleth/idp/module/conf/oidc.properties b/idp-oidc-extension-impl/src/test/resources/net/shibboleth/idp/module/conf/oidc.properties
index bdd53ca5..b996d9f7 100644
--- a/idp-oidc-extension-impl/src/test/resources/net/shibboleth/idp/module/conf/oidc.properties
+++ b/idp-oidc-extension-impl/src/test/resources/net/shibboleth/idp/module/conf/oidc.properties
@@ -37,3 +37,4 @@ idp.authn.OAuth2Client.audit.format = %a|%T|%SP|%I|%s|%AF|%CV|%u|%tu|%AR|%UA|%is
 idp.oidfed.authorize.automaticRegistrationCondition = shibboleth.Conditions.TRUE
 idp.oidfed.par.automaticRegistrationCondition = shibboleth.Conditions.TRUE
 idp.oidfed.configuration.resolver.values = CustomEntityConfigurationValues
+idp.oidfed.configuration.MetadataSkaletonFile = src/test/resources/net/shibboleth/idp/module/conf/oidfed-entity-configuration-metadata.json
\ No newline at end of file
diff --git a/idp-oidc-extension-impl/src/test/resources/net/shibboleth/idp/module/conf/oidfed-entity-configuration-metadata.json b/idp-oidc-extension-impl/src/test/resources/net/shibboleth/idp/module/conf/oidfed-entity-configuration-metadata.json
new file mode 100644
index 00000000..f4122635
--- /dev/null
+++ b/idp-oidc-extension-impl/src/test/resources/net/shibboleth/idp/module/conf/oidfed-entity-configuration-metadata.json
@@ -0,0 +1,7 @@
+{
+    "federation_entity": {
+        "organization_name" : "Example organization",
+        "organization_uri" : "https://org.example.org",
+        "contacts" : [ "contact at example.org" ]
+    }
+}
\ No newline at end of file
diff --git a/idp-oidc-extension-impl/src/test/resources/net/shibboleth/idp/module/conf/oidfed-trust-anchors.json b/idp-oidc-extension-impl/src/test/resources/net/shibboleth/idp/module/conf/oidfed/oidfed-trust-anchors.json
similarity index 100%
rename from idp-oidc-extension-impl/src/test/resources/net/shibboleth/idp/module/conf/oidfed-trust-anchors.json
rename to idp-oidc-extension-impl/src/test/resources/net/shibboleth/idp/module/conf/oidfed/oidfed-trust-anchors.json

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


More information about the commits mailing list