[java-idp-plugin-oidc-op-oidfed] branch main updated: Move resolve-entity flow and its dependencies into oidfed-common

Codeberg noreply at shibboleth.net
Tue Sep 22 15:22:42 UTC 2026


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

codeberg pushed a commit to branch main
in repository java-idp-plugin-oidc-op-oidfed.

View the commit online:
https://codeberg.org/Shibboleth/java-idp-plugin-oidc-op-oidfed/commit/fa315923d040ebf6fcff0c5a1dcaf25eeff40f92

The following commit(s) were added to refs/heads/main by this push:
     new fa31592  Move resolve-entity flow and its dependencies into oidfed-common
fa31592 is described below

commit fa315923d040ebf6fcff0c5a1dcaf25eeff40f92
Author: Henri Mikkonen <henri.mikkonen at iki.fi>
AuthorDate: Tue Sep 22 18:22:03 2026 +0300

    Move resolve-entity flow and its dependencies into oidfed-common
---
 .../context/RelyingPartyConfigurationSupport.java  |  61 ----
 .../context/logic/TrustAnchorIdPredicate.java      |  97 ------
 .../navigate/TrustAnchorIdLookupFunction.java      |  69 ----
 idp-oidfed-op-impl/pom.xml                         |   5 +
 .../decoding/impl/ResolveEntityRequestDecoder.java | 113 -------
 .../BuildResolveEntityErrorResponseFromEvent.java  | 270 ---------------
 .../profile/impl/BuildResolveEntityResponse.java   | 204 -----------
 .../impl/FormOutboundResolveEntityResponse.java    | 230 -------------
 .../impl/LookupCachedResolveEntityResponse.java    | 157 ---------
 .../oidfed/profile/impl/OidFederationEventIds.java |  84 -----
 .../profile/impl/ValidateProvidedTrustChain.java   |   1 +
 .../profile/impl/ValidateResolveEntityRequest.java | 186 -----------
 .../profile/impl/ValidateSelectedTrustChain.java   | 231 -------------
 .../navigate/DefaultEntityTypesLookupFunction.java |  46 ---
 .../META-INF/net.shibboleth.idp/postconfig.xml     |  48 ---
 .../oidfed/resolve-entity/resolve-entity-beans.xml | 218 ------------
 .../oidfed/resolve-entity/resolve-entity-flow.xml  | 112 -------
 .../idp/service/relying-party/postconfig.xml       |  11 -
 .../op/oidfed/conf/oidfed/oidfed-op.properties     |  22 --
 .../profile/flow/oidfed/ResolveEntityFlowTest.java | 371 ---------------------
 .../shibboleth/idp/module/conf/relying-party.xml   |  10 -
 21 files changed, 6 insertions(+), 2540 deletions(-)

diff --git a/idp-oidfed-op-api/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/context/RelyingPartyConfigurationSupport.java b/idp-oidfed-op-api/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/context/RelyingPartyConfigurationSupport.java
deleted file mode 100644
index 8d246c5..0000000
--- a/idp-oidfed-op-api/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/context/RelyingPartyConfigurationSupport.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package net.shibboleth.idp.plugin.oidc.op.oidfed.profile.context;
-
-import java.util.Collection;
-
-import javax.annotation.Nonnull;
-
-import net.shibboleth.idp.plugin.oidc.op.oidfed.profile.context.logic.TrustAnchorIdPredicate;
-import net.shibboleth.profile.relyingparty.BasicRelyingPartyConfiguration;
-import net.shibboleth.profile.relyingparty.RelyingPartyConfiguration;
-import net.shibboleth.shared.logic.Constraint;
-
-/**
- * Support functions for building {@link RelyingPartyConfiguration} objects with activation conditions.
- */
-public class RelyingPartyConfigurationSupport {
-
-    /**
-     * A shorthand method for constructing a {@link BasicRelyingPartyConfiguration} with an activation condition
-     * based on one or more trust anchor IDs.
-     * 
-     * <p>If a single ID is supplied, then the ID is also set as the identifier for the configuration.</p>
-     * 
-     * @param trustAnchorIds the trust anchors for which the configuration should be active
-     * 
-     * @return  a default-constructed configuration with the appropriate condition set
-     */
-    @Nonnull
-    public static BasicRelyingPartyConfiguration byTrustAnchor(@Nonnull final Collection<String> trustAnchorIds) {
-
-        Constraint.isNotNull(trustAnchorIds, "Trust Anchor ID list cannot be null");
-
-        final BasicRelyingPartyConfiguration config = new BasicRelyingPartyConfiguration(); 
-        config.setActivationCondition(new TrustAnchorIdPredicate(trustAnchorIds));
-        
-        final StringBuffer name = new StringBuffer("TrustAnchorIDs[");
-        for (final String taId: trustAnchorIds) {
-            name.append(taId).append(',');
-            
-        }
-        name.append(']');
-        final String id = name.toString();
-        assert id != null;
-        config.setId(id);
-        return config;
-    }
-
-}
diff --git a/idp-oidfed-op-api/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/context/logic/TrustAnchorIdPredicate.java b/idp-oidfed-op-api/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/context/logic/TrustAnchorIdPredicate.java
deleted file mode 100644
index 020b197..0000000
--- a/idp-oidfed-op-api/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/context/logic/TrustAnchorIdPredicate.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package net.shibboleth.idp.plugin.oidc.op.oidfed.profile.context.logic;
-
-import java.util.Collection;
-import java.util.function.Predicate;
-
-import javax.annotation.Nonnull;
-
-import org.opensaml.profile.context.ProfileRequestContext;
-
-import net.shibboleth.idp.plugin.oidc.op.oidfed.profile.context.navigate.TrustAnchorIdLookupFunction;
-import net.shibboleth.shared.annotation.ParameterName;
-import net.shibboleth.shared.annotation.constraint.NotEmpty;
-import net.shibboleth.shared.collection.CollectionSupport;
-import net.shibboleth.shared.logic.StrategyIndirectedPredicate;
-import net.shibboleth.shared.primitive.StringSupport;
-
-/**
- * Predicate that evaluates a {@link ProfileRequestContext} by looking for a trust anchor ID that matches one of a
- * designated set, or a generic predicate.
- */
-public class TrustAnchorIdPredicate extends StrategyIndirectedPredicate<ProfileRequestContext,String> {
-
-    /**
-     * Constructor.
-     * 
-     * @param candidates hardwired set of values to check against
-     */
-    public TrustAnchorIdPredicate(@Nonnull @ParameterName(name="candidates") final Collection<String> candidates) {
-        super(new TrustAnchorIdLookupFunction(), StringSupport.normalizeStringCollection(candidates));
-    }
-
-    /**
-     * Constructor.
-     * 
-     * @param candidate a single value to check against
-     */
-    public TrustAnchorIdPredicate(@Nonnull @NotEmpty @ParameterName(name="candidate") final String candidate) {
-        this(CollectionSupport.singleton(candidate));
-    }
-
-    /**
-     * Constructor.
-     * 
-     * @param pred generalized predicate
-     */
-    public TrustAnchorIdPredicate(@Nonnull @ParameterName(name="pred") final Predicate<String> pred) {
-        super(new TrustAnchorIdLookupFunction(), pred);
-    }
-    
-    /**
-     * Workaround for Spring type conversion ambiguities.
-     * 
-     * @param candidates hardwired set of values to check against
-     * 
-     * @return the predicate
-     */
-    @Nonnull public static TrustAnchorIdPredicate fromCandidates(@Nonnull final Collection<String> candidates) {
-        return new TrustAnchorIdPredicate(candidates);
-    }
-    
-    /**
-     * Workaround for Spring type conversion ambiguities.
-     * 
-     * @param candidate a single value to check against
-     * 
-     * @return the predicate
-     */
-    @Nonnull public static TrustAnchorIdPredicate fromCandidate(@Nonnull @NotEmpty final String candidate) {
-        return new TrustAnchorIdPredicate(candidate);
-    }
-
-    /**
-     * Workaround for Spring type conversion ambiguities.
-     * 
-     * @param pred generalized predicate
-     * 
-     * @return the predicate
-     */
-    @Nonnull public static TrustAnchorIdPredicate fromPredicate(@Nonnull final Predicate<String> pred) {
-        return new TrustAnchorIdPredicate(pred);
-    }
-
-}
diff --git a/idp-oidfed-op-api/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/context/navigate/TrustAnchorIdLookupFunction.java b/idp-oidfed-op-api/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/context/navigate/TrustAnchorIdLookupFunction.java
deleted file mode 100644
index b346e11..0000000
--- a/idp-oidfed-op-api/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/context/navigate/TrustAnchorIdLookupFunction.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package net.shibboleth.idp.plugin.oidc.op.oidfed.profile.context.navigate;
-
-import java.util.Optional;
-import java.util.function.Function;
-
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-import javax.annotation.concurrent.ThreadSafe;
-
-import org.opensaml.profile.context.ProfileRequestContext;
-
-import net.shibboleth.idp.plugin.oidc.op.profile.context.navigate.DefaultOIDCMetadataContextLookupFunction;
-import net.shibboleth.oidc.metadata.context.OIDCMetadataContext;
-import net.shibboleth.oidfed.support.ClientInformationExtensionSupport;
-import net.shibboleth.shared.logic.Constraint;
-
-/**
- * A function that returns {@link ClientInformationExtensionSupport#KEY_VALIDATED_TRUST_ANCHOR} if found from the
- * client information resolved via {@link OIDCMetadataContext}.
- * 
- * <p>If a specific setting is unavailable, a null value is returned.</p>
- */
- at ThreadSafe
-public class TrustAnchorIdLookupFunction implements Function<ProfileRequestContext, String> {
-
-    /** Strategy used to lookup the OIDC metadata context. */
-    @Nonnull private Function<ProfileRequestContext, OIDCMetadataContext> oidcMetadataContextLookupStrategy;
-
-    /**
-     * Constructor.
-     */
-    public TrustAnchorIdLookupFunction() {
-        oidcMetadataContextLookupStrategy = new DefaultOIDCMetadataContextLookupFunction();
-    }
-
-    /**
-     * Constructor.
-     *
-     * @param oidcMetadataStrategy strategy used to lookup the OIDC metadata context
-     */
-    public TrustAnchorIdLookupFunction(
-            @Nonnull final Function<ProfileRequestContext, OIDCMetadataContext> oidcMetadataStrategy) {
-        oidcMetadataContextLookupStrategy = Constraint.isNotNull(oidcMetadataStrategy,
-                "OIDC metadata context lookup strategy cannot be null");
-    }
-
-    /** {@inheritDoc} */
-    @Nullable public String apply(@Nullable final ProfileRequestContext profileRequestContext) {
-        return Optional.ofNullable(oidcMetadataContextLookupStrategy.apply(profileRequestContext))
-                .map(oidcContext -> oidcContext.getClientInformation())
-                .map(clientInfo -> clientInfo != null ?
-                        ClientInformationExtensionSupport.parseValidatedTrustAnchor(clientInfo) : null)
-                .orElse(null);
-    }
-}
diff --git a/idp-oidfed-op-impl/pom.xml b/idp-oidfed-op-impl/pom.xml
index ac345b0..2f66a8b 100644
--- a/idp-oidfed-op-impl/pom.xml
+++ b/idp-oidfed-op-impl/pom.xml
@@ -70,6 +70,11 @@
             <artifactId>oidc-common-profile-impl</artifactId>
             <scope>provided</scope>
         </dependency>
+        <dependency>
+            <groupId>${oidc-common.groupId}</groupId>
+            <artifactId>oidc-common-conf-impl</artifactId>
+            <scope>provided</scope>
+        </dependency>
         <dependency>
             <groupId>${oidfed-common.groupId}</groupId>
             <artifactId>oidfed-common-api</artifactId>
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/decoding/impl/ResolveEntityRequestDecoder.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/decoding/impl/ResolveEntityRequestDecoder.java
deleted file mode 100644
index ad03e4d..0000000
--- a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/decoding/impl/ResolveEntityRequestDecoder.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package net.shibboleth.idp.plugin.oidc.op.oidfed.decoding.impl;
-
-import java.io.IOException;
-import java.net.URI;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Optional;
-
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-
-import org.opensaml.messaging.decoder.MessageDecodingException;
-import org.slf4j.Logger;
-
-import com.google.common.base.MoreObjects;
-import com.nimbusds.oauth2.sdk.ParseException;
-import com.nimbusds.oauth2.sdk.auth.ClientAuthentication;
-import com.nimbusds.oauth2.sdk.http.HTTPRequest;
-import com.nimbusds.oauth2.sdk.http.JakartaServletUtils;
-
-import jakarta.servlet.http.HttpServletRequest;
-import net.shibboleth.idp.plugin.oidc.op.decoding.impl.RequestUtil;
-import net.shibboleth.idp.plugin.oidc.op.oauth2.decoding.impl.BaseOAuth2RequestDecoder;
-import net.shibboleth.oidfed.messaging.impl.ResolveEntityRequest;
-import net.shibboleth.shared.primitive.LoggerFactory;
-
-/**
- * Message decoder decoding OpenID Federation Resolve Entity request {@link ResolveEntityRequest}.
- */
-public class ResolveEntityRequestDecoder extends BaseOAuth2RequestDecoder<ResolveEntityRequest> {
-
-    /** Class logger. */
-    @Nonnull private final Logger log = LoggerFactory.getLogger(ResolveEntityRequestDecoder.class);
-
-    /** {@inheritDoc} */
-    @Override
-    protected ResolveEntityRequest parseMessage() throws MessageDecodingException {
-        final HttpServletRequest request = getHttpServletRequest();
-        assert request != null;
-        if (!"GET".equalsIgnoreCase(request.getMethod()) && !"POST".equalsIgnoreCase(request.getMethod())) {
-            throw new MessageDecodingException("This message decoder only supports the HTTP GET and POST methods");
-        }
-        if (!"application/x-www-form-urlencoded".equals(request.getContentType())) {
-            throw new MessageDecodingException("Invalid content type: " + request.getContentType());
-        }
-        try {
-            final HTTPRequest httpRequest = JakartaServletUtils.createHTTPRequest(request);
-            getProtocolMessageLogger().trace("Inbound request {}", RequestUtil.toString(httpRequest, null));
-            final URI uri = httpRequest.getURI();
-            if (uri == null) {
-                throw new MessageDecodingException("Could not parse request URI");
-            }
-            final ClientAuthentication clientAuthentication = ClientAuthentication.parse(httpRequest);
-            if (clientAuthentication != null && !"POST".equalsIgnoreCase(request.getMethod())) {
-                throw new MessageDecodingException(
-                        "This message decoder requires use of POST method when client authentication is involved");
-            }
-            if (clientAuthentication == null && !"GET".equalsIgnoreCase(request.getMethod())) {
-                throw new MessageDecodingException(
-                        "This message decoder requires use of GET method when client authentication is not involved");
-            }
-            final Map<String, List<String>> parameters = httpRequest.getQueryParameters();
-            final String subject = Optional.ofNullable(parameters.get("sub"))
-                    .filter(Objects::nonNull)
-                    .filter(list -> list.size() == 1)
-                    .map(list -> list.get(0))
-                    .orElse(null);
-            if (subject == null) {
-                throw new MessageDecodingException("No single sub value in the request");
-            }
-            final List<String> trustAnchors = Optional.ofNullable(parameters.get("trust_anchor"))
-                    .filter(Objects::nonNull)
-                    .filter(list -> list.size() > 0)
-                    .orElse(null);
-            if (trustAnchors == null) {
-                throw new MessageDecodingException("No trust_anchor included in the request");
-            }
-            return new ResolveEntityRequest(uri, subject, trustAnchors, parameters.get("entity_type"),
-                    clientAuthentication);
-        } catch (final IOException | ParseException e) {
-            log.error("Could not create HTTP request from the request", e);
-            throw new MessageDecodingException(e);
-        }
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected String getMessageToLog(@Nullable final ResolveEntityRequest message) {
-        return message == null ? null : MoreObjects.toStringHelper(this).omitNullValues()
-                .add("subject", message.getSubject())
-                .add("trustAnchors", message.getTrustAnchors())
-                .add("entityTypes", message.getEntityTypes())
-                .add("endpointURI", getEndpointURI(message))
-                .add("clientAuthentication", RequestUtil.getClientAuthenticationLog(message.getClientAuthentication()))
-                .toString();
-    }
-
-}
\ No newline at end of file
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/BuildResolveEntityErrorResponseFromEvent.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/BuildResolveEntityErrorResponseFromEvent.java
deleted file mode 100644
index 527f119..0000000
--- a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/BuildResolveEntityErrorResponseFromEvent.java
+++ /dev/null
@@ -1,270 +0,0 @@
-/*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package net.shibboleth.idp.plugin.oidc.op.oidfed.profile.impl;
-
-import java.time.Duration;
-import java.time.Instant;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.function.Function;
-
-import javax.annotation.Nonnull;
-
-import org.opensaml.messaging.context.navigate.ChildContextLookup;
-import org.opensaml.profile.context.EventContext;
-import org.opensaml.profile.context.ProfileRequestContext;
-import org.opensaml.profile.context.navigate.CurrentOrPreviousEventLookup;
-import org.opensaml.profile.context.navigate.InboundMessageContextLookup;
-import org.slf4j.Logger;
-
-import com.nimbusds.oauth2.sdk.ErrorObject;
-import com.nimbusds.oauth2.sdk.ErrorResponse;
-import com.nimbusds.oauth2.sdk.http.HTTPResponse;
-
-import net.shibboleth.idp.profile.AbstractProfileAction;
-import net.shibboleth.oidc.metadata.cache.MetadataCache;
-import net.shibboleth.oidc.metadata.cache.MetadataCacheException;
-import net.shibboleth.oidc.profile.messaging.JSONErrorResponse;
-import net.shibboleth.oidfed.messaging.impl.ResolveEntityRequest;
-import net.shibboleth.oidfed.metadata.cache.ResponseContainerExpirationCriterion;
-import net.shibboleth.oidfed.metadata.cache.local.NimbusResponseCriterion;
-import net.shibboleth.oidfed.metadata.cache.local.ResolveEntityRequestCriterion;
-import net.shibboleth.oidfed.metadata.cache.local.ResolveEntityResponseContainer;
-import net.shibboleth.oidfed.profile.config.navigate.CachedErrorResponseLifetimeLookupFunction;
-import net.shibboleth.oidfed.profile.impl.RelyingPartyCachedMessageContext;
-import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
-import net.shibboleth.shared.component.ComponentInitializationException;
-import net.shibboleth.shared.logic.Constraint;
-import net.shibboleth.shared.primitive.LoggerFactory;
-import net.shibboleth.shared.resolver.CriteriaSet;
-
-/**
- * This action reads an event from the configured {@link EventContext} lookup strategy, constructs a JSON error response
- * message and attaches it as the outbound message. If {@link RelyingPartyCachedMessageContext} is found, it's exploited
- * for storing the response message in the configured {@link #responseCache}.
- */
-public class BuildResolveEntityErrorResponseFromEvent extends AbstractProfileAction {
-
-    /** Default value for the error code in the error response messages. */
-    public static final String DEFAULT_ERROR_CODE = "invalid_request";
-    
-    /** Default value for the HTTP response status code in the HTTP responses. */
-    public static final int DEFAULT_HTTP_STATUS_CODE = HTTPResponse.SC_BAD_REQUEST;
-
-    /** Class logger. */
-    @Nonnull private final Logger log = LoggerFactory.getLogger(BuildResolveEntityErrorResponseFromEvent.class);
-
-    /** Strategy function for access to {@link EventContext} to check. */
-    @Nonnull
-    private Function<ProfileRequestContext, EventContext> eventContextLookupStrategy;
-
-    /** Map of eventIds to pre-configured error objects. */
-    private Map<String, ErrorObject> mappedErrors;
-
-    /** The status code for unmapped events. */
-    private int defaultStatusCode;
-
-    /** The code for unmapped events. */
-    private String defaultCode;
-
-    /** Metadata cache for cached response containers. */
-    @NonnullAfterInit private MetadataCache<ResolveEntityResponseContainer> responseCache;
-
-    /** Strategy used to locate the lifetime for the cached response record. */
-    @Nonnull private Function<ProfileRequestContext,Duration> cachedResponseLifetimeLookupStrategy;
-
-    /** Strategy used to locate the resolve entity context. */
-    @Nonnull
-    private Function<ProfileRequestContext, RelyingPartyCachedMessageContext> resolveEntityContextLookupStrategy;
-
-    /**
-     * Constructor.
-     */
-    public BuildResolveEntityErrorResponseFromEvent() {
-        eventContextLookupStrategy = new CurrentOrPreviousEventLookup();
-        mappedErrors = new HashMap<>();
-        defaultStatusCode = DEFAULT_HTTP_STATUS_CODE;
-        defaultCode = DEFAULT_ERROR_CODE;
-        cachedResponseLifetimeLookupStrategy = new CachedErrorResponseLifetimeLookupFunction();
-        final Function<ProfileRequestContext, RelyingPartyCachedMessageContext> recls =
-                new ChildContextLookup<>(RelyingPartyCachedMessageContext.class).compose(
-                        new InboundMessageContextLookup());
-        assert recls != null;
-        resolveEntityContextLookupStrategy = recls;
-
-    }
-
-    /**
-     * Set the status code for unmapped events.
-     * 
-     * @param code The default status code for unmapped events.
-     */
-    public void setDefaultStatusCode(final int code) {
-        defaultStatusCode = code;
-    }
-
-    /**
-     * Set the code for unmapped events.
-     * 
-     * @param code The default status code for unmapped events.
-     */
-    public void setDefaultCode(@Nonnull final String code) {
-        defaultCode = Constraint.isNotNull(code, "Default code cannot be null");
-    }
-
-    /**
-     * Set lookup strategy for {@link EventContext} to check.
-     * 
-     * @param strategy lookup strategy
-     */
-    public void setEventContextLookupStrategy(@Nonnull final Function<ProfileRequestContext, EventContext> strategy) {
-        ifInitializedThrowUnmodifiabledComponentException();
-
-        eventContextLookupStrategy = Constraint.isNotNull(strategy, "EventContext lookup strategy cannot be null");
-    }
-
-    /**
-     * Set map of eventIds to pre-configured error objects.
-     * 
-     * @param errors map of eventIds to pre-configured error objects.
-     */
-    public void setMappedErrors(@Nonnull final Map<String, ErrorObject> errors) {
-        ifInitializedThrowUnmodifiabledComponentException();
-
-        mappedErrors = Constraint.isNotNull(errors, "Mapped errors cannot be null");
-    }
-
-    /**
-     * Set the metadata cache for cached response containers.
-     * 
-     * @param cache What to set.
-     */
-    public void setResponseCache(@Nonnull final MetadataCache<ResolveEntityResponseContainer> cache) {
-        checkSetterPreconditions();
-        responseCache = Constraint.isNotNull(cache, "Response metadata cache cannot be null");
-    }
-
-    /**
-     * Set the strategy used to locate the lifetime for the cached response record.
-     * 
-     * @param strategy What to set.
-     */
-    public void setCachedResponseLifetimeLookupStrategy(
-            @Nonnull final Function<ProfileRequestContext, Duration> strategy) {
-        checkSetterPreconditions();
-        cachedResponseLifetimeLookupStrategy = Constraint.isNotNull(strategy, "Lookup strategy cannot be null");
-    }
-
-    /**
-     * Set the strategy used to locate the resolve entity context
-     * 
-     * @param strategy What to set.
-     */
-    public void setResolveEntityContextLookupStrategy(
-            @Nonnull final Function<ProfileRequestContext,RelyingPartyCachedMessageContext> strategy) {
-        checkSetterPreconditions();
-        resolveEntityContextLookupStrategy = Constraint.isNotNull(strategy, "Lookup strategy cannot be null!");
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected void doInitialize() throws ComponentInitializationException {
-        super.doInitialize();
-
-        if (responseCache == null) {
-            throw new ComponentInitializationException("Response metadata cache cannot be null");
-        }
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected boolean doPreExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
-        
-        if (!super.doPreExecute(profileRequestContext)) {
-            return false;
-        }
-        
-        if (profileRequestContext.getOutboundMessageContext() == null) {
-            log.debug("{} No outbound message context initialized, nothing to do", getLogPrefix());
-            return false;
-        }
-        
-        return true;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
-        final EventContext eventCtx = eventContextLookupStrategy.apply(profileRequestContext);
-        if (eventCtx == null || eventCtx.getEvent() == null) {
-            log.error("{} No event to be included in the response, nothing to do", getLogPrefix());
-            return;
-        }
-        assert eventCtx != null;
-        final Object event = eventCtx.getEvent();
-        assert event != null;
-        final String eventValue = event.toString();
-        final ErrorObject error;
-        if (mappedErrors.containsKey(eventValue)) {
-            log.debug("{} Found mapped event for {}", getLogPrefix(), eventValue);
-            error = mappedErrors.get(eventValue);
-        } else {
-            log.debug("{} No mapped event found for {}, creating general {}", getLogPrefix(), eventValue, defaultCode);
-            error = new ErrorObject(defaultCode, eventValue, defaultStatusCode);
-        }
-        assert error != null;
-        final ErrorResponse errorResponse = buildErrorResponse(error, profileRequestContext);
-        if (errorResponse != null) {
-            profileRequestContext.ensureOutboundMessageContext().setMessage(errorResponse);
-            log.debug("{} ErrorResponse successfully set as the outbound message", getLogPrefix());
-        } else {
-            log.debug("{} Error response not formed", getLogPrefix());
-        }
-    }
-
-    protected JSONErrorResponse buildErrorResponse(@Nonnull final ErrorObject error,
-            @Nonnull final ProfileRequestContext profileRequestContext) {
-        final JSONErrorResponse response = new JSONErrorResponse(error);
-        final RelyingPartyCachedMessageContext resolveEntityContext =
-                resolveEntityContextLookupStrategy.apply(profileRequestContext);
-
-        final Duration cachedResponseLifetime = cachedResponseLifetimeLookupStrategy.apply(profileRequestContext);
-        if (resolveEntityContext != null && cachedResponseLifetime != null &&
-                resolveEntityContext.getValidatedRequest() instanceof ResolveEntityRequest resolveEntityRequest) {
-            final NimbusResponseCriterion responseCriterion = new NimbusResponseCriterion(response);
-            final Instant expiration = Instant.now().plus(cachedResponseLifetime);
-            assert expiration != null;
-            final ResponseContainerExpirationCriterion expirationCriterion =
-                    new ResponseContainerExpirationCriterion(expiration);
-            final ResolveEntityRequestCriterion requestCriterion =
-                    new ResolveEntityRequestCriterion(resolveEntityRequest);
-            final CriteriaSet criteria = new CriteriaSet(requestCriterion, responseCriterion, expirationCriterion);
-            try {
-                final List<ResolveEntityResponseContainer> result = responseCache.get(criteria);
-                if (result.size() != 1) {
-                    log.error("{} Unexpected result (size={}) when storing response record into the metadata cache",
-                            getLogPrefix(), result.size());
-                } else {
-                    log.debug("{} Response stored into the cache", getLogPrefix());
-                }
-            } catch (final MetadataCacheException e) {
-                log.error("{} Could not store the response record into the metadata cache", getLogPrefix(), e);
-            }
-        }
-
-        return response;
-    }
-}
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
deleted file mode 100644
index dae1be2..0000000
--- a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/BuildResolveEntityResponse.java
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package net.shibboleth.idp.plugin.oidc.op.oidfed.profile.impl;
-
-import java.time.Instant;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Optional;
-import java.util.function.Function;
-import java.util.stream.Collectors;
-
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-
-import org.opensaml.messaging.context.navigate.ChildContextLookup;
-import org.opensaml.profile.action.ActionSupport;
-import org.opensaml.profile.action.EventIds;
-import org.opensaml.profile.context.ProfileRequestContext;
-import org.opensaml.profile.context.navigate.InboundMessageContextLookup;
-import org.slf4j.Logger;
-
-import com.nimbusds.jwt.JWTClaimsSet;
-
-import net.shibboleth.idp.plugin.oidc.op.oidfed.profile.navigate.DefaultEntityTypesLookupFunction;
-import net.shibboleth.oidfed.metadata.EntityStatement;
-import net.shibboleth.oidfed.metadata.TrustMark;
-import net.shibboleth.oidfed.metadata.payload.claim.Metadata;
-import net.shibboleth.oidfed.profile.context.RelyingPartyTrustChainContext;
-import net.shibboleth.oidfed.profile.context.VerifiedTrustChain;
-import net.shibboleth.oidfed.profile.impl.AbstractBuildEntityStatementAction;
-import net.shibboleth.shared.annotation.constraint.NonnullBeforeExec;
-import net.shibboleth.shared.collection.Pair;
-import net.shibboleth.shared.logic.Constraint;
-import net.shibboleth.shared.primitive.LoggerFactory;
-
-/**
- * An action that uses the information from {@link RelyingPartyTrustChainContext} for creating a new JWT to be used for
- * creating a response to OpenID Federation Resolve Entity API.
- */
-public class BuildResolveEntityResponse extends AbstractBuildEntityStatementAction {
-
-    /** Class logger. */
-    @Nonnull private final Logger log = LoggerFactory.getLogger(BuildResolveEntityResponse.class);
-
-    /** Strategy used to lookup the trust chain context. */
-    @Nonnull private Function<ProfileRequestContext, RelyingPartyTrustChainContext> trustChainContextLookupStrategy;
-
-    /** Strategy used to lookup the entity types included in the response metadata. */
-    @Nonnull private Function<ProfileRequestContext, List<String>> entityTypesLookupStrategy;
-
-    /** Trust chain context to operate on. */
-    @NonnullBeforeExec private RelyingPartyTrustChainContext trustChainContext;
-
-    /** Constructor. */
-    public BuildResolveEntityResponse() {
-        final Function<ProfileRequestContext, RelyingPartyTrustChainContext> tcls =
-                new ChildContextLookup<>(RelyingPartyTrustChainContext.class).compose(
-                        new InboundMessageContextLookup());
-        assert tcls != null;
-        trustChainContextLookupStrategy = tcls;
-        entityTypesLookupStrategy = new DefaultEntityTypesLookupFunction();
-    }
-    
-    /**
-     * Set the strategy used to lookup the trust chain context.
-     * 
-     * @param strategy lookup strategy
-     */
-    public void setTrustChainContextLookupStrategy(
-            @Nonnull final Function<ProfileRequestContext, RelyingPartyTrustChainContext> strategy) {
-        checkSetterPreconditions();
-        trustChainContextLookupStrategy =
-                Constraint.isNotNull(strategy, "TrustChainContextLookupStrategy cannot be null");
-    }
-
-    /**
-     * Set the strategy used to lookup the entity types included in the response metadata.
-     * 
-     * @param strategy lookup strategy
-     */
-    public void setEntityTypesLookupStrategy(@Nonnull final Function<ProfileRequestContext, List<String>> strategy) {
-        checkSetterPreconditions();
-        entityTypesLookupStrategy = Constraint.isNotNull(strategy, "EntityTypesLookupStrategy cannot be null");
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected boolean doPreExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
-        if (!super.doPreExecute(profileRequestContext)) {
-            return false;
-        }
-
-        trustChainContext = trustChainContextLookupStrategy.apply(profileRequestContext);
-        if (trustChainContext == null) {
-            log.error("{} Unable to locate trust chain context", getLogPrefix());
-            ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_MSG_CTX);
-            return false;
-        }
-
-        return true;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected boolean populateClaimsSetBuilder(@Nonnull final JWTClaimsSet.Builder builder,
-            @Nonnull final ProfileRequestContext profileRequestContext) {
-        final VerifiedTrustChain 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 Metadata metadata = selectedTrustChain.getMetadata();
-        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.getAllClaims().entrySet()
-                    .stream()
-                    .filter(entry -> entityTypes.contains(entry.getKey()))
-                    .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
-            if  (filteredMetadata.isEmpty()) {
-                log.warn("{} No metadata for entity types {} found for the selected trust chain", getLogPrefix(),
-                        entityTypes);
-                ActionSupport.buildEvent(profileRequestContext, OidFederationEventIds.INVALID_METADATA);
-                return false;
-            }
-            builder.claim("metadata", filteredMetadata);
-        } else {
-            builder.claim("metadata", metadata);
-        }
-
-        final List<EntityStatement<?>> trustChain = selectedTrustChain.getTrustChain();
-        builder.claim("trust_chain", trustChain.stream()
-                .map(statement -> statement.getJwt().serialize())
-                .toList());
-
-        final Instant expirationTime = resolveTrustChainExpiration(trustChain);
-        if (expirationTime == null) {
-            log.error("{} Coud not resolve expiration time from the selected trust chain context", getLogPrefix());
-            ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_MSG_CTX);
-            return false;
-        }
-        builder.expirationTime(Date.from(expirationTime));
-
-        final String entityId = trustChain.get(0).getSubject();
-        assert entityId != null;
-        final Map<String, String> trustMarks = buildTrustMarks(entityId, trustChainContext.getVerifiedTrustMarks());
-        if (trustMarks != null && !trustMarks.isEmpty()) {
-            builder.claim("trust_marks", trustMarks);
-        }
-        return true;
-    }
-
-    /**
-     * Builds value for the trust_marks claim in the resolve entity response entity statement.
-     * 
-     * @param entityId the subject entity ID
-     * @param trustMarks trust marks for the selected trust chain
-     * @return map of trust marks, keyed with trust mark IDs
-     */
-    @Nullable private Map<String, String> buildTrustMarks(@Nonnull final String entityId,
-            @Nullable final Map<String, List<TrustMark>> trustMarks) {
-        return Optional.ofNullable(trustMarks)
-            .map(marks -> marks.get(entityId))
-            .filter(Objects::nonNull)
-            .map(list -> list.stream()
-                    .map(trustMark -> new Pair<String, String>(
-                            trustMark.getParsedPayload().getTrustMarkType(), trustMark.getJwt().serialize()))
-                    .filter(Objects::nonNull)
-                    .collect(Collectors.toMap(pair -> pair.getFirst(), pair -> pair.getSecond())))
-            .orElse(null);
-    }
-
-    /**
-     * Resolve expiration time for the given trust chain.
-     * 
-     * @param trustChain trust chain
-     * @return expiration time
-     */
-    @Nullable private Instant resolveTrustChainExpiration(@Nonnull final List<EntityStatement<?>> trustChain) {
-        Instant metadataExpiration = null;
-        for (final EntityStatement<?> statement : trustChain) {
-            final Instant statementExpiration = statement.getParsedPayload().getExpiration();
-            metadataExpiration = metadataExpiration == null ? statementExpiration : 
-                statementExpiration.isBefore(metadataExpiration) ? statementExpiration : metadataExpiration;
-        }
-        return metadataExpiration;
-    }
-
-}
\ No newline at end of file
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/FormOutboundResolveEntityResponse.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/FormOutboundResolveEntityResponse.java
deleted file mode 100644
index 99d1ecb..0000000
--- a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/FormOutboundResolveEntityResponse.java
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package net.shibboleth.idp.plugin.oidc.op.oidfed.profile.impl;
-
-import java.time.Duration;
-import java.time.Instant;
-import java.util.List;
-import java.util.function.Function;
-
-import javax.annotation.Nonnull;
-
-import org.opensaml.messaging.context.navigate.ChildContextLookup;
-import org.opensaml.profile.action.ActionSupport;
-import org.opensaml.profile.action.EventIds;
-import org.opensaml.profile.context.ProfileRequestContext;
-import org.opensaml.profile.context.navigate.InboundMessageContextLookup;
-import org.opensaml.profile.context.navigate.OutboundMessageContextLookup;
-import org.slf4j.Logger;
-
-import com.nimbusds.jwt.SignedJWT;
-import com.nimbusds.oauth2.sdk.Response;
-
-import net.shibboleth.idp.profile.AbstractProfileAction;
-import net.shibboleth.oidc.metadata.cache.MetadataCache;
-import net.shibboleth.oidc.metadata.cache.MetadataCacheException;
-import net.shibboleth.oidfed.messaging.impl.ResolveEntityRequest;
-import net.shibboleth.oidfed.messaging.impl.ResolveEntityResponse;
-import net.shibboleth.oidfed.metadata.cache.ResponseContainerExpirationCriterion;
-import net.shibboleth.oidfed.metadata.cache.local.NimbusResponseCriterion;
-import net.shibboleth.oidfed.metadata.cache.local.ResolveEntityRequestCriterion;
-import net.shibboleth.oidfed.metadata.cache.resolver.ResolveEntityResponseContainer;
-import net.shibboleth.oidfed.profile.config.navigate.CachedSuccessResponseLifetimeLookupFunction;
-import net.shibboleth.oidfed.profile.impl.EntityStatementContext;
-import net.shibboleth.oidfed.profile.impl.RelyingPartyCachedMessageContext;
-import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
-import net.shibboleth.shared.annotation.constraint.NonnullBeforeExec;
-import net.shibboleth.shared.component.ComponentInitializationException;
-import net.shibboleth.shared.logic.Constraint;
-import net.shibboleth.shared.primitive.LoggerFactory;
-import net.shibboleth.shared.resolver.CriteriaSet;
-
-/**
- * This action builds a response for the OpenID federation resolve entity request. The response contains an
- * {@link SignedJWT}. The response is put in the {@link #responseCache} using the lifetime resolved via
- * {@link #cachedResponseLifetimeLookupStrategy}.
- */
-public class FormOutboundResolveEntityResponse extends AbstractProfileAction {
-
-    /** Class logger. */
-    @Nonnull private final Logger log = LoggerFactory.getLogger(FormOutboundResolveEntityResponse.class);
-
-    /** Metadata cache for cached response containers. */
-    @NonnullAfterInit private MetadataCache<ResolveEntityResponseContainer> responseCache;
-
-    /** Strategy used to locate the resolve entity context. */
-    @Nonnull
-    private Function<ProfileRequestContext, RelyingPartyCachedMessageContext> cachedMessageContextLookupStrategy;
-
-    /** Strategy used to locate the subcontext to hold the statement. */
-    @Nonnull private Function<ProfileRequestContext,EntityStatementContext> entityStatementContextLookupStrategy;
-
-    /** Strategy used to locate the lifetime for the cached response record. */
-    @Nonnull private Function<ProfileRequestContext,Duration> cachedResponseLifetimeLookupStrategy;
-
-    /** JWT used to build entity statement. */
-    @NonnullBeforeExec private SignedJWT jwt;
-
-    /** The resolve entity context to operate on. */
-    @NonnullBeforeExec private RelyingPartyCachedMessageContext cachedMessageContext;
-
-    /**
-     * Constructor.
-     */
-    public FormOutboundResolveEntityResponse() {
-        final Function<ProfileRequestContext,EntityStatementContext> escls =
-                new ChildContextLookup<>(EntityStatementContext.class).compose(
-                        new OutboundMessageContextLookup());
-        assert escls != null;
-        entityStatementContextLookupStrategy = escls;
-        final Function<ProfileRequestContext, RelyingPartyCachedMessageContext> recls =
-                new ChildContextLookup<>(RelyingPartyCachedMessageContext.class).compose(
-                        new InboundMessageContextLookup());
-        assert recls != null;
-        cachedMessageContextLookupStrategy = recls;
-        cachedResponseLifetimeLookupStrategy = new CachedSuccessResponseLifetimeLookupFunction();
-    }
-
-    /**
-     * Set the strategy used to locate the subcontext to hold the statement
-     * 
-     * @param strategy What to set.
-     */
-    public void setEntityStatementContextLookupStrategy(
-            @Nonnull final Function<ProfileRequestContext,EntityStatementContext> strategy) {
-        checkSetterPreconditions();
-        entityStatementContextLookupStrategy = Constraint.isNotNull(strategy, "Lookup strategy cannot be null!");
-    }
-
-    /**
-     * Set the strategy used to locate the cached message context
-     * 
-     * @param strategy What to set.
-     */
-    public void setCachedMessageContextLookupStrategy(
-            @Nonnull final Function<ProfileRequestContext,RelyingPartyCachedMessageContext> strategy) {
-        checkSetterPreconditions();
-        cachedMessageContextLookupStrategy = Constraint.isNotNull(strategy, "Lookup strategy cannot be null!");
-    }
-
-    /**
-     * Set the metadata cache for cached response containers.
-     * 
-     * @param cache What to set.
-     */
-    public void setResponseCache(@Nonnull final MetadataCache<ResolveEntityResponseContainer> cache) {
-        checkSetterPreconditions();
-        responseCache = Constraint.isNotNull(cache, "Response metadata cache cannot be null");
-    }
-
-    /**
-     * Set the strategy used to locate the lifetime for the cached response record.
-     * 
-     * @param strategy What to set.
-     */
-    public void setCachedResponseLifetimeLookupStrategy(
-            @Nonnull final Function<ProfileRequestContext, Duration> strategy) {
-        checkSetterPreconditions();
-        cachedResponseLifetimeLookupStrategy = Constraint.isNotNull(strategy, "Lookup strategy cannot be null");
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected void doInitialize() throws ComponentInitializationException {
-        super.doInitialize();
-
-        if (responseCache == null) {
-            throw new ComponentInitializationException("Response metadata cache cannot be null");
-        }
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected boolean doPreExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
-
-        if (!super.doPreExecute(profileRequestContext)) {
-            return false;
-        }
-        cachedMessageContext = cachedMessageContextLookupStrategy.apply(profileRequestContext);
-        if (cachedMessageContext == null) {
-            log.error("{} Could not resolve cached message context", getLogPrefix());
-            ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_PROFILE_CTX);
-            return false;
-        }
-
-        return true;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
-        final Response cachedResponse = cachedMessageContext.getCachedResponse();
-        if (cachedResponse != null) {
-            log.debug("{} Cached response found, storing in to the outbound message context", getLogPrefix());
-            profileRequestContext.ensureOutboundMessageContext().setMessage(cachedResponse);
-            return;
-        }
-        log.debug("{} No cached response found, resolving the response JWT from the context", getLogPrefix());
-        final EntityStatementContext entityStatementContext =
-                entityStatementContextLookupStrategy.apply(profileRequestContext);
-        if (entityStatementContext == null) {
-            log.error("{} Could not resolve entity statement context", getLogPrefix());
-            ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_PROFILE_CTX);
-            return;
-        }
-        if (entityStatementContext.getJWT() instanceof SignedJWT signedJwt) {
-            jwt = signedJwt;
-        } else {
-            log.error("{} No signed JWT found from the entity statement context", getLogPrefix());
-            ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_PROFILE_CTX);
-            return;
-        }
-
-        assert jwt != null;
-        final ResolveEntityResponse response = new ResolveEntityResponse(jwt);
-        final NimbusResponseCriterion responseCriterion = new NimbusResponseCriterion(response);
-        final Duration lifetime = cachedResponseLifetimeLookupStrategy.apply(profileRequestContext);
-        if (lifetime == null) {
-            log.error("{} Could not resolve lifetime for the cached response record", getLogPrefix());
-            ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_PROFILE_CTX);
-            return;
-        }
-        final Instant expiration = Instant.now().plus(lifetime);
-        assert expiration != null;
-        final ResponseContainerExpirationCriterion expirationCriterion =
-                new ResponseContainerExpirationCriterion(expiration);
-        if (cachedMessageContext.getValidatedRequest() instanceof ResolveEntityRequest validatedRequest) {
-            final ResolveEntityRequestCriterion requestCriterion = new ResolveEntityRequestCriterion(validatedRequest);
-            final CriteriaSet criteria = new CriteriaSet(requestCriterion, responseCriterion, expirationCriterion);
-            try {
-                final List<ResolveEntityResponseContainer> result = responseCache.get(criteria);
-                if (result.size() != 1) {
-                    log.error("{} Unexpected result (size={}) when storing response record into the metadata cache",
-                            getLogPrefix(), result.size());
-                } else {
-                    log.debug("{} Response stored into the cache", getLogPrefix());
-                }
-            } catch (final MetadataCacheException e) {
-                log.error("{} Could not store the response record into tht metadata cache", getLogPrefix(), e);
-            }
-        } else {
-            log.error("{} No validated request found from the resolve entity context", getLogPrefix());
-            ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_PROFILE_CTX);
-            return;
-        }
-
-        profileRequestContext.ensureOutboundMessageContext().setMessage(response);
-    }
-}
\ No newline at end of file
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/LookupCachedResolveEntityResponse.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/LookupCachedResolveEntityResponse.java
deleted file mode 100644
index e6a5632..0000000
--- a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/LookupCachedResolveEntityResponse.java
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package net.shibboleth.idp.plugin.oidc.op.oidfed.profile.impl;
-
-import java.util.List;
-import java.util.function.Function;
-
-import javax.annotation.Nonnull;
-
-import org.opensaml.messaging.context.navigate.ChildContextLookup;
-import org.opensaml.profile.action.ActionSupport;
-import org.opensaml.profile.action.EventIds;
-import org.opensaml.profile.context.ProfileRequestContext;
-import org.opensaml.profile.context.navigate.InboundMessageContextLookup;
-import org.slf4j.Logger;
-
-import net.shibboleth.idp.profile.AbstractProfileAction;
-import net.shibboleth.oidc.metadata.cache.MetadataCache;
-import net.shibboleth.oidc.metadata.cache.MetadataCacheException;
-import net.shibboleth.oidfed.messaging.impl.ResolveEntityRequest;
-import net.shibboleth.oidfed.metadata.cache.local.ResolveEntityRequestCriterion;
-import net.shibboleth.oidfed.metadata.cache.local.ResolveEntityResponseContainer;
-import net.shibboleth.oidfed.profile.impl.RelyingPartyCachedMessageContext;
-import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
-import net.shibboleth.shared.annotation.constraint.NonnullBeforeExec;
-import net.shibboleth.shared.component.ComponentInitializationException;
-import net.shibboleth.shared.logic.Constraint;
-import net.shibboleth.shared.primitive.LoggerFactory;
-import net.shibboleth.shared.resolver.CriteriaSet;
-
-/**
- * Lookup if a cached response already exists for the validated resolve entity API request. If yes, the response is
- * stored into {@link RelyingPartyCachedMessageContext} and a corresponding event ID is published.
- * 
- * @event {@link EventIds#PROCEED_EVENT_ID}
- * @event {@link EventIds#INVALID_PROFILE_CTX}
- * @event {@link OidFederationEventIds#CACHED_RESPONSE_FOUND}
- */
-public class LookupCachedResolveEntityResponse extends AbstractProfileAction {
-
-    /** Class logger. */
-    @Nonnull private Logger log = LoggerFactory.getLogger(LookupCachedResolveEntityResponse.class);
-
-    /** Strategy used to locate the cached message context. */
-    @Nonnull
-    private Function<ProfileRequestContext, RelyingPartyCachedMessageContext> cachedMessageContextLookupStrategy;
-
-    /** Metadata cache for cached response containers. */
-    @NonnullAfterInit private MetadataCache<ResolveEntityResponseContainer> responseCache;
-
-    /** Cached message context to operate on. */
-    @NonnullBeforeExec private RelyingPartyCachedMessageContext cachedMessageContext;
-
-    /** Request message to operate on. */
-    @NonnullBeforeExec private ResolveEntityRequest validatedRequest;
-
-    /**
-     * Constructor.
-     */
-    public LookupCachedResolveEntityResponse() {
-        final Function<ProfileRequestContext, RelyingPartyCachedMessageContext> recls =
-                new ChildContextLookup<>(RelyingPartyCachedMessageContext.class).compose(
-                        new InboundMessageContextLookup());
-        assert recls != null;
-        cachedMessageContextLookupStrategy = recls;
-    }
-
-    /**
-     * Set the strategy used to locate the cached message context
-     * 
-     * @param strategy What to set.
-     */
-    public void setCachedMessageContextLookupStrategy(
-            @Nonnull final Function<ProfileRequestContext,RelyingPartyCachedMessageContext> strategy) {
-        checkSetterPreconditions();
-        cachedMessageContextLookupStrategy = Constraint.isNotNull(strategy, "Lookup strategy cannot be null!");
-    }
-
-    /**
-     * Set the metadata cache for cached response containers.
-     * 
-     * @param cache What to set.
-     */
-    public void setResponseCache(@Nonnull final MetadataCache<ResolveEntityResponseContainer> cache) {
-        checkSetterPreconditions();
-        responseCache = Constraint.isNotNull(cache, "Response metadata cache cannot be null");
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected void doInitialize() throws ComponentInitializationException {
-        super.doInitialize();
-        if (responseCache == null) {
-            throw new ComponentInitializationException("Response metadata cache cannot be null");
-        }
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected boolean doPreExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
-        if (!super.doPreExecute(profileRequestContext)) {
-            return false;
-        }
-
-        cachedMessageContext = cachedMessageContextLookupStrategy.apply(profileRequestContext);
-        if (cachedMessageContext == null) {
-            log.error("{} Could not resolve cached response context", getLogPrefix());
-            ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_PROFILE_CTX);
-            return false;
-        }
-        
-        if (cachedMessageContext.getValidatedRequest() instanceof ResolveEntityRequest resolveEntityRequest) {
-            validatedRequest = resolveEntityRequest;
-        } else {
-            log.error("{} Could not resolve validated resolve entity request", getLogPrefix());
-            ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_PROFILE_CTX);
-            return false;
-        }
-
-        return true;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
-        assert validatedRequest != null;
-        final ResolveEntityRequestCriterion requestCriterion = new ResolveEntityRequestCriterion(validatedRequest);
-        final CriteriaSet criteria = new CriteriaSet(requestCriterion);
-        try {
-            final List<ResolveEntityResponseContainer> result = responseCache.get(criteria);
-            if (result.size() != 1) {
-                log.debug("{} No cached response record found from the metadata cache", getLogPrefix(), result.size());
-            } else {
-                final ResolveEntityResponseContainer cachedResponse = result.get(0);
-                cachedMessageContext.setCachedResponse(cachedResponse.getResponse());
-                log.debug("{} Response found from the cache, publishing event {}", getLogPrefix(),
-                        OidFederationEventIds.CACHED_RESPONSE_FOUND);
-                ActionSupport.buildEvent(profileRequestContext, OidFederationEventIds.CACHED_RESPONSE_FOUND);
-                return;
-            }
-        } catch (final MetadataCacheException e) {
-            log.error("{} Could not fetch response record from the metadata cache", getLogPrefix(), e);
-        }
-   }
-}
\ No newline at end of file
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/OidFederationEventIds.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/OidFederationEventIds.java
deleted file mode 100644
index 9c5752c..0000000
--- a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/OidFederationEventIds.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package net.shibboleth.idp.plugin.oidc.op.oidfed.profile.impl;
-
-import javax.annotation.Nonnull;
-
-import net.shibboleth.shared.annotation.constraint.NotEmpty;
-
-/**
- * OpenID Federation -specific constants to use for {@link org.opensaml.profile.action.ProfileAction}
- * {@link org.opensaml.profile.context.EventContext}s.
- */
-public class OidFederationEventIds {
-
-    /**
-     * ID of event returned if a flow wishes to indicate that another trust chain should be selected instead
-     */
-    @Nonnull @NotEmpty public static final String RESELECT_TRUST_CHAIN = "ReselectTrustChain";
-
-    /**
-     * ID of event returned if cached response was found and set to the context.
-     */
-    @Nonnull @NotEmpty public static final String CACHED_RESPONSE_FOUND = "CachedResponseFound";
-
-    /**
-     * ID of event returned if no trust chains were resolved for the client.
-     */
-    @Nonnull @NotEmpty public static final String NO_TRUST_CHAINS_RESOLVED = "NoTrustChainsResolved";
-
-    /**
-     * ID of event returned if the given trust anchor is invalid.
-     */
-    @Nonnull @NotEmpty public static final String INVALID_TRUST_ANCHOR = "InvalidTrustAnchor";
-
-    /**
-     * ID of event returned if the given subject is invalid.
-     */
-    @Nonnull @NotEmpty public static final String INVALID_SUBJECT = "InvalidSubject";
-
-    /**
-     * ID of event returned if the given metadata is invalid.
-     */
-    @Nonnull @NotEmpty public static final String INVALID_METADATA = "InvalidMetadata";
-
-    /**
-     * ID of event returned if the given metadata policy is invalid.
-     */
-    @Nonnull @NotEmpty public static final String INVALID_METADATA_POLICY = "InvalidMetadataPolicy";
-
-    /**
-     * ID of event returned if the given metadata is invalid against policy.
-     */
-    @Nonnull @NotEmpty public static final String INVALID_METADATA_AGAINST_POLICY = "InvalidMetadataAgainstPolicy";
-
-    /**
-     * ID of event returned if the trust chain is invalid against constraints.
-     */
-    @Nonnull @NotEmpty public static final String INVALID_TRUST_CHAIN_AGAINST_CONSTRAINTS =
-            "InvalidTrustChainAgainstConstraints";
-
-    /**
-     * ID of event returned if the mandatory provided trust chain could not be fetched.
-     */
-    @Nonnull @NotEmpty public static final String MISSING_MANDATORY_PROVIDED_TRUST_CHAIN =
-            "MissingMandatoryProvidedTrustChain";
-
-    /**
-     * ID of event returned if the provided trust chain could not be verified.
-     */
-    @Nonnull @NotEmpty public static final String INVALID_PROVIDED_TRUST_CHAIN = "InvalidProvidedTrustChain";
-
-}
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 57d089f..8a40d65 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.oidfed.metadata.EntityStatement;
+import net.shibboleth.oidfed.profile.OidFederationEventIds;
 import net.shibboleth.oidfed.profile.ProvidedTrustChainResolver;
 import net.shibboleth.oidfed.profile.context.RelyingPartyTrustChainContext;
 import net.shibboleth.oidfed.profile.context.VerifiedTrustChain;
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/ValidateResolveEntityRequest.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/ValidateResolveEntityRequest.java
deleted file mode 100644
index 683e6b7..0000000
--- a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/ValidateResolveEntityRequest.java
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package net.shibboleth.idp.plugin.oidc.op.oidfed.profile.impl;
-
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.function.Function;
-
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-
-import org.opensaml.messaging.context.navigate.ChildContextLookup;
-import org.opensaml.profile.action.ActionSupport;
-import org.opensaml.profile.action.EventIds;
-import org.opensaml.profile.context.ProfileRequestContext;
-import org.opensaml.profile.context.navigate.InboundMessageContextLookup;
-import org.slf4j.Logger;
-
-import com.nimbusds.oauth2.sdk.Request;
-
-import net.shibboleth.idp.profile.AbstractProfileAction;
-import net.shibboleth.oidc.metadata.cache.MetadataCache;
-import net.shibboleth.oidc.metadata.cache.MetadataCacheException;
-import net.shibboleth.oidfed.messaging.impl.ResolveEntityRequest;
-import net.shibboleth.oidfed.metadata.cache.SubjectEntityIDCriterion;
-import net.shibboleth.oidfed.metadata.cache.local.LocalKeyContainer;
-import net.shibboleth.oidfed.profile.impl.RelyingPartyCachedMessageContext;
-import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
-import net.shibboleth.shared.annotation.constraint.NonnullBeforeExec;
-import net.shibboleth.shared.component.ComponentInitializationException;
-import net.shibboleth.shared.logic.Constraint;
-import net.shibboleth.shared.primitive.LoggerFactory;
-import net.shibboleth.shared.primitive.StringSupport;
-import net.shibboleth.shared.resolver.CriteriaSet;
-
-/**
- * Validates the resolve entity request against the profile configuration and stores the validated (possibly modified)
- * request into {@link RelyingPartyCachedMessageContext#setValidatedRequest(Request)}.
- * 
- * @event {@link EventIds#PROCEED_EVENT_ID}
- * @event {@link EventIds#INVALID_MSG_CTX}
- */
-public class ValidateResolveEntityRequest extends AbstractProfileAction {
-
-    /** Class logger. */
-    @Nonnull private Logger log = LoggerFactory.getLogger(ValidateResolveEntityRequest.class);
-
-    /** Strategy used to create the cached message context. */
-    @Nonnull
-    private Function<ProfileRequestContext, RelyingPartyCachedMessageContext> cachedMessageContextCreationStrategy;
-
-    /** Cache containing local copies of trusted trust anchor keys. */
-    @NonnullAfterInit private MetadataCache<Map<String, LocalKeyContainer>> localTrustAnchorsCache;
-
-    /** Request message to operate on. */
-    @NonnullBeforeExec private ResolveEntityRequest requestMessage;
-
-    /** Cached message context to operate on. */
-    @NonnullBeforeExec private RelyingPartyCachedMessageContext cachedMessageContext;
-
-    /**
-     * Constructor.
-     */
-    public ValidateResolveEntityRequest() {
-        final Function<ProfileRequestContext, RelyingPartyCachedMessageContext> reccs =
-                new ChildContextLookup<>(RelyingPartyCachedMessageContext.class, true).compose(
-                        new InboundMessageContextLookup());
-        assert reccs != null;
-        cachedMessageContextCreationStrategy = reccs;
-    }
-
-    /**
-     * Set the strategy used to return or create the resolve entity context.
-     * 
-     * @param strategy creation strategy
-     */
-    public void setResolveEntityContextCreationStrategy(
-            @Nonnull final Function<ProfileRequestContext, RelyingPartyCachedMessageContext> strategy) {
-        checkSetterPreconditions();
-        cachedMessageContextCreationStrategy = Constraint.isNotNull(strategy,
-                "RelyingPartyResolveEntityContext creation strategy cannot be null");
-    }
-
-    /**
-     * Set the strategy used to lookup the trust chain context.
-     * 
-     * @param cache lookup strategy
-     */
-    public void setLocalTrustAnchorsCache(
-            @Nonnull final MetadataCache<Map<String, LocalKeyContainer>> cache) {
-        checkSetterPreconditions();
-        localTrustAnchorsCache =
-                Constraint.isNotNull(cache, "LocalTrustAnchorsCache cannot be null");
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected void doInitialize() throws ComponentInitializationException {
-        super.doInitialize();
-        if (localTrustAnchorsCache == null) {
-            throw new ComponentInitializationException("LocalTrustAnchorsCache cannot be null");
-        }
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected boolean doPreExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
-        if (!super.doPreExecute(profileRequestContext)) {
-            return false;
-        }
-
-        requestMessage = Optional.ofNullable(profileRequestContext.getInboundMessageContext())
-                .map(messageContext -> messageContext.getMessage())
-                .filter(ResolveEntityRequest.class::isInstance)
-                .map(ResolveEntityRequest.class::cast)
-                .orElse(null);
-        if (requestMessage == null) {
-            log.error("{} Unable to fetch the request message to operate on", getLogPrefix());
-            ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_PROFILE_CTX);
-            return false;
-        }
-        
-        cachedMessageContext = cachedMessageContextCreationStrategy.apply(profileRequestContext);
-        if (cachedMessageContext == null) {
-            log.error("{} Unable to create resolve entity context", getLogPrefix());
-            ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_PROFILE_CTX);
-            return false;
-        }
-        return true;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
-        final List<String> validatedAnchors = requestMessage.getTrustAnchors().stream()
-                .filter(anchor -> isLocallyTrusted(anchor))
-                .toList();
-        if (validatedAnchors.isEmpty()) {
-            log.info("{} No locally trusted anchors left after filtering", getLogPrefix());
-            ActionSupport.buildEvent(profileRequestContext, OidFederationEventIds.INVALID_TRUST_ANCHOR);
-            return;
-        }
-        log.debug("{} The following trust anchors were validated: {}", getLogPrefix(), validatedAnchors);
-        cachedMessageContext.setValidatedRequest(
-                new ResolveEntityRequest(requestMessage.getEndpointURI(), requestMessage.getSubject(),
-                        validatedAnchors, requestMessage.getEntityTypes(), requestMessage.getClientAuthentication()));
-    }
-
-    /**
-     * Verifies whether the given trust anchor candidate is locally trusted.
-     * 
-     * @param candidate the trust anchor candidate
-     * @return true if locally trusted, false otherwise
-     */
-    protected boolean isLocallyTrusted(@Nullable final String candidate) {
-        if (StringSupport.trimOrNull(candidate) == null) {
-            return false;
-        }
-        assert candidate != null;
-        final SubjectEntityIDCriterion criterion = new SubjectEntityIDCriterion(candidate);
-        try {
-            final List<Map<String,LocalKeyContainer>> result = localTrustAnchorsCache.get(new CriteriaSet(criterion));
-            if (result.isEmpty() || result.get(0).isEmpty()) {
-                log.debug("{} No locally trusted keys found for {}", getLogPrefix(), candidate);
-                return false;
-            }
-            return result.get(0).containsKey(candidate);
-        } catch (final MetadataCacheException e) {
-            log.error("{} Could not fetch value for {} from the metadata cache", getLogPrefix(), candidate, e);
-        }
-        return false;
-    }
-}
\ No newline at end of file
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
deleted file mode 100644
index d585f54..0000000
--- a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/impl/ValidateSelectedTrustChain.java
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package net.shibboleth.idp.plugin.oidc.op.oidfed.profile.impl;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.function.Function;
-
-import javax.annotation.Nonnull;
-
-import org.opensaml.profile.action.EventIds;
-import org.opensaml.profile.context.ProfileRequestContext;
-import org.opensaml.profile.context.navigate.InboundMessageContextLookup;
-import org.slf4j.Logger;
-
-import net.shibboleth.idp.profile.AbstractProfileAction;
-import net.shibboleth.oidc.metadata.cache.MetadataCache;
-import net.shibboleth.oidc.metadata.cache.MetadataCacheException;
-import net.shibboleth.oidfed.messaging.impl.ResolveEntityRequest;
-import net.shibboleth.oidfed.metadata.EntityStatement;
-import net.shibboleth.oidfed.metadata.cache.SubjectEntityIDCriterion;
-import net.shibboleth.oidfed.metadata.cache.configuration.EntityConfigurationContainer;
-import net.shibboleth.oidfed.profile.context.RelyingPartyTrustChainContext;
-import net.shibboleth.oidfed.profile.context.VerifiedTrustChain;
-import net.shibboleth.oidfed.profile.impl.RelyingPartyCachedMessageContext;
-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.resolver.CriteriaSet;
-
-import org.opensaml.messaging.context.navigate.ChildContextLookup;
-import org.opensaml.profile.action.ActionSupport;
-
-/**
- * Validates that the currenty selected trust chain meets the trust anchor requirements in the resolve entity request.
- * If not and if other candidates remains, {@link OidFederationEventIds#RESELECT_TRUST_CHAIN} is published. If no other
- * candidates are available, {@link OidFederationEventIds#INVALID_TRUST_ANCHOR} or
- * {@link OidFederationEventIds#INVALID_SUBJECT} is published.
- * 
- * @event {@link EventIds#PROCEED_EVENT_ID}
- * @event {@link EventIds#INVALID_MSG_CTX}
- * @event {@link OidFederationEventIds#RESELECT_TRUST_CHAIN}
- * @event {@link OidFederationEventIds#INVALID_TRUST_ANCHOR}
- * @event {@link OidFederationEventIds#INVALID_SUBJECT}
- */
-public class ValidateSelectedTrustChain extends AbstractProfileAction {
-
-    /** Class logger. */
-    @Nonnull private Logger log = LoggerFactory.getLogger(ValidateSelectedTrustChain.class);
-
-    /** Metadata cache for entity configurations. */
-    @NonnullAfterInit private MetadataCache<EntityConfigurationContainer> entityConfigurationCache;
-
-    /** Strategy used to lookup the trust chain context. */
-    @Nonnull private Function<ProfileRequestContext, RelyingPartyTrustChainContext> trustChainContextLookupStrategy;
-
-    /** Strategy used to locate the resolve entity context. */
-    @Nonnull
-    private Function<ProfileRequestContext, RelyingPartyCachedMessageContext> resolveEntityContextLookupStrategy;
-
-    /** The validated request to operate on. */
-    @NonnullBeforeExec private ResolveEntityRequest validatedRequest;
-
-    /**
-     * Constructor.
-     */
-    public ValidateSelectedTrustChain() {
-        final Function<ProfileRequestContext, RelyingPartyTrustChainContext> tcls =
-                new ChildContextLookup<>(RelyingPartyTrustChainContext.class).compose(
-                        new InboundMessageContextLookup());
-        assert tcls != null;
-        trustChainContextLookupStrategy = tcls;
-        final Function<ProfileRequestContext, RelyingPartyCachedMessageContext> recls =
-                new ChildContextLookup<>(RelyingPartyCachedMessageContext.class).compose(
-                        new InboundMessageContextLookup());
-        assert recls != null;
-        resolveEntityContextLookupStrategy = recls;
-    }
-
-    /**
-     * Set the metadata cache for entity configurations.
-     * 
-     * @param cache What to set.
-     */
-    public void setEntityConfigurationCache(@Nonnull final MetadataCache<EntityConfigurationContainer> cache) {
-        checkSetterPreconditions();
-        entityConfigurationCache = Constraint.isNotNull(cache, "Entity configuration metadata cache cannot be null");
-    }
-
-    /**
-     * Set the strategy used to lookup the trust chain context.
-     * 
-     * @param strategy lookup strategy
-     */
-    public void setTrustChainContextLookupStrategy(
-            @Nonnull final Function<ProfileRequestContext, RelyingPartyTrustChainContext> strategy) {
-        checkSetterPreconditions();
-        trustChainContextLookupStrategy =
-                Constraint.isNotNull(strategy, "TrustChainContextLookupStrategy cannot be null");
-    }
-
-    /**
-     * Set the strategy used to locate the resolve entity context
-     * 
-     * @param strategy What to set.
-     */
-    public void setResolveEntityContextLookupStrategy(
-            @Nonnull final Function<ProfileRequestContext,RelyingPartyCachedMessageContext> strategy) {
-        checkSetterPreconditions();
-        resolveEntityContextLookupStrategy = Constraint.isNotNull(strategy, "Lookup strategy cannot be null!");
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected void doInitialize() throws ComponentInitializationException {
-        super.doInitialize();
-
-        if (entityConfigurationCache == null) {
-            throw new ComponentInitializationException("Entity configuration metadata cache cannot be null");
-        }
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected boolean doPreExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
-        if (!super.doPreExecute(profileRequestContext)) {
-            return false;
-        }
-
-        final RelyingPartyCachedMessageContext cachedResponseContext =
-                resolveEntityContextLookupStrategy.apply(profileRequestContext);
-        if (cachedResponseContext == null) {
-            log.error("{} Could not resolve cached message context", getLogPrefix());
-            ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_PROFILE_CTX);
-            return false;
-        }
-
-        if (cachedResponseContext.getValidatedRequest() instanceof ResolveEntityRequest resolveEntityRequest) {
-            validatedRequest = resolveEntityRequest;
-        } else {
-            log.error("{} Could not resolve request message", getLogPrefix());
-            ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_PROFILE_CTX);
-            return false;
-        }
-
-        return true;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
-        final RelyingPartyTrustChainContext trustChainContext =
-                trustChainContextLookupStrategy.apply(profileRequestContext);
-        final VerifiedTrustChain selectedTrustChain =
-                trustChainContext != null ? trustChainContext.getSelectedTrustChain() : null;
-        if (selectedTrustChain == null) {
-            final List<VerifiedTrustChain> allChains =
-                    trustChainContext != null ? trustChainContext.getPolicyCompliantTrustChains() : null;
-            if (allChains == null || allChains.isEmpty()) {
-                if (isSubjectValid(validatedRequest.getSubject())) {
-                    log.debug("{} No trust chains were resolved, subject is valid", getLogPrefix());
-                    ActionSupport.buildEvent(profileRequestContext, OidFederationEventIds.INVALID_TRUST_ANCHOR);
-                    return;
-                } else {
-                    log.debug("{} No trust chains were resolved, subject is not valid", getLogPrefix());
-                    ActionSupport.buildEvent(profileRequestContext, OidFederationEventIds.INVALID_SUBJECT);
-                    return;
-                }
-            } else {
-                log.debug("{} No trust chains left to choose from", getLogPrefix());
-                ActionSupport.buildEvent(profileRequestContext, OidFederationEventIds.INVALID_TRUST_ANCHOR);
-                return;
-            }
-        }
-        
-        final List<String> trustAnchors = validatedRequest.getTrustAnchors();
-        final List<EntityStatement<?>> candidateChain = selectedTrustChain.getTrustChain();
-        assert candidateChain != null;
-        final String candidateAnchor = candidateChain.get(candidateChain.size() - 1).getSubject();
-        if (!trustAnchors.contains(candidateAnchor)) {
-            log.debug("{} Selected trust chain candidate has unrequested trust anchor {}", getLogPrefix(),
-                    candidateAnchor);
-            assert trustChainContext != null;
-            final List<List<EntityStatement<?>>> rejectedTrustChains = trustChainContext.getRejectedTrustChains();
-            if (rejectedTrustChains == null) {
-                trustChainContext.setRejectedTrustChains(List.of(selectedTrustChain.getTrustChain()));
-            } else {
-                final List<List<EntityStatement<?>>> rejectedChains = new ArrayList<>(rejectedTrustChains);
-                rejectedChains.add(selectedTrustChain.getTrustChain());
-                trustChainContext.setRejectedTrustChains(CollectionSupport.copyToList(rejectedChains));
-            }
-            ActionSupport.buildEvent(profileRequestContext, OidFederationEventIds.RESELECT_TRUST_CHAIN);
-            return;
-        }
-    }
-
-    /**
-     * Checks if an entity configuration can be resolved for the given subject and it's thus valid for federation.
-     * 
-     * @param subject the subject to be verified
-     * @return true if the given subject is valid, false otherwise.
-     */
-    protected boolean isSubjectValid(@Nonnull final String subject) {
-        final SubjectEntityIDCriterion subjectCriterion = new SubjectEntityIDCriterion(subject);
-        try {
-            final List<EntityConfigurationContainer> result =
-                    entityConfigurationCache.get(new CriteriaSet(subjectCriterion));
-            if (result.size() == 1 && result.get(0).getStatement() != null) {
-                return true;
-            }
-        } catch (final MetadataCacheException e) {
-            log.debug("{} Exception catched when resolving entty configuration", e);
-        }
-        return false;
-    }
-}
\ No newline at end of file
diff --git a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/navigate/DefaultEntityTypesLookupFunction.java b/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/navigate/DefaultEntityTypesLookupFunction.java
deleted file mode 100644
index e2bd6d2..0000000
--- a/idp-oidfed-op-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oidfed/profile/navigate/DefaultEntityTypesLookupFunction.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package net.shibboleth.idp.plugin.oidc.op.oidfed.profile.navigate;
-
-import java.util.List;
-import java.util.Optional;
-import java.util.function.Function;
-
-import javax.annotation.Nullable;
-
-import org.opensaml.profile.context.ProfileRequestContext;
-
-import net.shibboleth.oidfed.messaging.impl.ResolveEntityRequest;
-import net.shibboleth.shared.collection.CollectionSupport;
-import net.shibboleth.shared.primitive.NonnullSupplier;
-
-/**
- * Default function to lookup entity types to be included to the response metadata.
- */
-public class DefaultEntityTypesLookupFunction implements Function<ProfileRequestContext, List<String>> {
-
-    /** {@inheritDoc} */
-    @Override @Nullable
-    public List<String> apply(@Nullable final ProfileRequestContext profileRequestContext) {
-        return Optional.ofNullable(profileRequestContext)
-                .map(prc -> prc.getInboundMessageContext())
-                .map(msgCtx -> msgCtx.getMessage())
-                .filter(ResolveEntityRequest.class::isInstance)
-                .map(ResolveEntityRequest.class::cast)
-                .map(req -> req.getEntityTypes())
-                .orElseGet(NonnullSupplier.of(CollectionSupport.emptyList()));
-    }
-
-}
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 3f1d26f..a45f92a 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
@@ -51,39 +51,6 @@
 
     <bean p:id="oidc/metadata-lookup-ext/oidfed" parent="shibboleth.oidc.MetadataLookupExtensionFlow" />
 
-    <bean id="shibboleth.oidc.DefaultResolveEntityApiMappedErrors"
-            parent="shibboleth.oidc.DefaultApiMappedErrors"
-            class="org.springframework.beans.factory.config.MapFactoryBean">
-        <property name="sourceMap">
-            <map merge="true" value-type="com.nimbusds.oauth2.sdk.ErrorObject">
-                <entry>
-                    <key>
-                        <util:constant static-field="org.opensaml.profile.action.EventIds.INVALID_MSG_CTX"/>
-                    </key>
-                    <bean class="com.nimbusds.oauth2.sdk.ErrorObject" c:_0="server_error" c:_1="Internal server error" c:_2="500" />
-                </entry>
-                <entry>
-                    <key>
-                        <util:constant static-field="net.shibboleth.oidfed.profile.OidFederationEventIds.INVALID_TRUST_ANCHOR"/>
-                    </key>
-                    <bean class="com.nimbusds.oauth2.sdk.ErrorObject" c:_0="invalid_trust_anchor" c:_1="Trust anchor in the request is invalid" c:_2="404" />
-                </entry>
-                <entry>
-                    <key>
-                        <util:constant static-field="net.shibboleth.oidfed.profile.OidFederationEventIds.INVALID_SUBJECT"/>
-                    </key>
-                    <bean class="com.nimbusds.oauth2.sdk.ErrorObject" c:_0="invalid_subject" c:_1="Subject in the request is invalid" c:_2="404" />
-                </entry>
-                <entry>
-                    <key>
-                        <util:constant static-field="net.shibboleth.oidfed.profile.OidFederationEventIds.INVALID_METADATA"/>
-                    </key>
-                    <bean class="com.nimbusds.oauth2.sdk.ErrorObject" c:_0="invalid_metadata" c:_1="Metadata is invalid or not found for the requested entity types" c:_2="400" />
-                </entry>
-            </map>
-        </property>
-    </bean>
-
     <bean id="shibboleth.oidfed.register.DefaultMappedErrors"
             parent="shibboleth.oidc.register.DefaultMappedErrors"
             class="org.springframework.beans.factory.config.MapFactoryBean">
@@ -186,9 +153,6 @@
                 <entry key="#{T(net.shibboleth.oidc.profile.config.OIDCUserInfoConfiguration).PROFILE_ID}">
                     <ref bean="shibboleth.oidfed.userinfo.DefaultAutomaticRegistrationCondition"/>
                 </entry>
-                <entry key="#{T(net.shibboleth.oidfed.profile.config.OIDFederationResolveEntityProfileConfiguration).PROFILE_ID}">
-                    <ref bean="shibboleth.oidfed.resolve-entity.DefaultAutomaticRegistrationCondition"/>
-                </entry>
             </util:map>
         </property>
     </bean>
@@ -283,14 +247,6 @@
         </constructor-arg>
     </bean>
 
-    <bean id="shibboleth.oidfed.resolve-entity.DefaultAutomaticRegistrationCondition" parent="shibboleth.Conditions.AND">
-        <constructor-arg>
-            <list>
-                <ref bean="%{idp.oidfed.resolve-entity.automaticRegistrationCondition:shibboleth.Conditions.TRUE}"/>
-            </list>
-        </constructor-arg>
-    </bean>
-
     <bean class="net.shibboleth.idp.plugin.oidc.op.security.jwt.claims.RequestObjectClaimsValidator">
         <constructor-arg>
             <bean id="shibboleth.oidfed.DefaultRequestObjectClaimsValidation"
@@ -411,10 +367,6 @@
         </property>
     </bean>
 
-    <!-- Property-based definition of login flows for the resolve-entity endpoint. -->    
-    <bean id="shibboleth.oidfed.resolver.PotentialFlows" class="org.springframework.beans.factory.config.ListFactoryBean"
-        p:sourceList="#{getObject('shibboleth.AuthenticationFlowDescriptorManager').getComponents().?[id matches 'authn/(' + '%{idp.oidfed.resolve-entity.authn.flows:OAuth2Client}'.trim() + ')']}" />
-
     <bean id="ProviderMetadataEntityConfigurationMetadataDecorator"
         class="net.shibboleth.idp.plugin.oidc.op.oidfed.profile.impl.ProviderMetadataEntityConfigurationMetadataDecorator"
         p:metadataResolver-ref="#{'%{idp.oidfed.op.metadata.resolver:shibboleth.oidfed.DefaultOpenIdConfigurationResolver}'.trim()}"/>
diff --git a/idp-oidfed-op-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidfed/resolve-entity/resolve-entity-beans.xml b/idp-oidfed-op-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidfed/resolve-entity/resolve-entity-beans.xml
deleted file mode 100644
index 4c41d7a..0000000
--- a/idp-oidfed-op-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidfed/resolve-entity/resolve-entity-beans.xml
+++ /dev/null
@@ -1,218 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<beans xmlns="http://www.springframework.org/schema/beans" xmlns:c="http://www.springframework.org/schema/c"
-    xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
-    xmlns:util="http://www.springframework.org/schema/util" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
-                           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
-                           http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"
-    default-init-method="initialize" default-destroy-method="destroy">
-
-    <bean id="shibboleth.oidc.profileId" class="java.lang.String"
-        c:_0="#{T(net.shibboleth.oidfed.profile.config.OIDFederationResolveEntityProfileConfiguration).PROFILE_ID}" />
-
-    <bean id="shibboleth.oidc.loggingId" class="java.lang.String" c:_0="%{idp.service.logging.oidfedresolve:OIDFED.ResolveEntity}" />
-
-    <bean id="shibboleth.oidc.browserProfile" class="java.lang.Boolean" c:_0="false" />
-
-    <util:constant id="shibboleth.metrics.ProfileCounter"
-        static-field="net.shibboleth.oidfed.profile.config.impl.DefaultOIDFederationResolveEntityProfileConfiguration.PROFILE_COUNTER" />
-
-    <bean id="DecodeMessage" class="org.opensaml.profile.action.impl.DecodeMessage" scope="prototype">
-        <constructor-arg>
-            <bean class="net.shibboleth.idp.plugin.oidc.op.oidfed.decoding.impl.ResolveEntityRequestDecoder" scope="prototype"
-                p:httpServletRequestSupplier-ref="shibboleth.HttpServletRequestSupplier"
-                p:removeIpAddressFromEndpointUri="%{idp.oidc.logging.removeIpAddressFromProtocolMessage:false}"/>
-                <!-- TODO: support custom parsing? p:customRequestParser="#{getObject('%{idp.oidfed.requestParser.ResolveEntityRequest:}'.trim())}"/>-->
-        </constructor-arg>
-    </bean>
-
-    <bean id="InitializeOutboundMessageContext"
-        class="net.shibboleth.idp.plugin.oidc.op.profile.impl.InitializeOutboundResponseMessageContext"
-        scope="prototype" />
-
-    <bean id="shibboleth.ClientIDLookupStrategy" parent="shibboleth.Functions.Expression" c:expression="#input.getMessage().getClientAuthentication() != null ? #input.getMessage().getClientAuthentication().getClientID() : new com.nimbusds.oauth2.sdk.id.ClientID(#input.getMessage().getSubject())" />
-
-    <bean id="InitializeRelyingPartyContext"
-        class="net.shibboleth.idp.plugin.oidc.op.profile.impl.InitializeRelyingPartyContext" scope="prototype"
-        p:clientIDLookupStrategy-ref="shibboleth.ClientIDLookupStrategy"
-        p:inbound="true" />
-
-    <bean id="InitializeAuthenticationContext"
-        class="net.shibboleth.idp.saml.profile.impl.InitializeAuthenticationContext" scope="prototype" />
-
-    <bean id="shibboleth.oidfed.ResolveEntityResponseMetadataCache" parent="shibboleth.oidc.CacheBuilder">
-        <constructor-arg>
-            <bean p:cacheId="DefaultResolveEntityResponseMetadataCache" parent="shibboleth.oidfed.ResolveEntityResponseMetadataCacheBuilderSpec"
-                p:cleanupTaskInterval="PT30S"/>
-        </constructor-arg>
-    </bean>
-
-    <bean id="shibboleth.oidfed.ResolveEntityResponseMetadataCacheBuilderSpec"
-        class="net.shibboleth.oidc.metadata.cache.impl.DynamicMetadataCacheBuilderSpec"
-        p:minCacheDuration="%{idp.oidfed.cache.resolveEntity.minRefreshDelay:PT1S}"
-        p:maxCacheDuration="%{idp.oidfed.cache.resolveEntity.maxRefreshDelay:PT30S}">
-        <property name="criteriaToIdentifierStrategy">
-            <bean parent="shibboleth.Functions.Expression"
-                c:expression="#input?.get(T(net.shibboleth.oidfed.metadata.cache.local.ResolveEntityRequestCriterion))?.getRequest().toString()"/>
-        </property>
-        <property name="identifierExtractionStrategy">
-            <bean parent="shibboleth.Functions.Expression"
-                c:expression="#input?.getRequest()?.toString()"/>
-        </property>
-        <property name="metadataExpirationTimeStrategy">
-            <bean class="net.shibboleth.oidfed.metadata.cache.local.DefaultNimbusResponseContainerExpirationTimeStrategy"/>
-        </property>
-        <property name="metadataFilterStrategy">
-            <bean parent="shibboleth.BiFunctions.Expression" c:expression="#input1"/>
-        </property>
-        <property name="fetchStrategy">
-            <bean class="net.shibboleth.oidfed.metadata.cache.local.DefaultResolveEntityResponseFetchingStrategy" />
-        </property>
-    </bean>
-
-    <bean id="ValidateRequest" class="net.shibboleth.idp.plugin.oidc.op.oidfed.profile.impl.ValidateResolveEntityRequest"
-        scope="prototype"
-        p:localTrustAnchorsCache-ref="#{'%{idp.oidfed.resolve-entity.LocalTrustAnchorsMetadataCache:shibboleth.oidfed.LocalTrustAnchorsMetadataCache}'.trim()}" />
-
-    <bean id="LookupCachedResolveEntityResponse"
-        class="net.shibboleth.idp.plugin.oidc.op.oidfed.profile.impl.LookupCachedResolveEntityResponse"
-        scope="prototype"
-        p:responseCache-ref="shibboleth.oidfed.ResolveEntityResponseMetadataCache" />
-
-    <bean id="shibboleth.oidfed.trust-chain-resolver.EntityIDLookupStrategy"
-        parent="shibboleth.Functions.Expression"
-        c:expression="#custom.apply(#input)">
-        <property name="customObject">
-            <bean  parent="shibboleth.Functions.Expression" c:expression="#input.getInboundMessageContext()?.getMessage()?.getSubject()" />
-        </property>
-    </bean>
-
-    <bean id="DefaultMetadataPolicyEnforcer"
-        class="net.shibboleth.oidfed.metadata.policy.impl.DefaultFederationMetadataPolicyEnforcer"
-        p:metadataPolicyOperators-ref="#{'%{idp.oidfed.resolve-entity.MetadataPolicyOperatorsy:shibboleth.oidfed.StandardMetadataPolicyOperators}'.trim()}"/>
-
-    <bean id="DefaultTrustChainMetadataPolicyMergingStrategy" 
-        class="net.shibboleth.oidfed.profile.navigate.DefaultTrustChainMetadataPolicyMergingStrategy"
-        p:metadataPolicyMergingStrategy-ref="#{'%{idp.oidfed.resolve-entity.MetadataPolicMergingyStrategy:MetadataPolicMergingyStrategy}'.trim()}"
-        p:localMetadataPolicyStrategy-ref="#{'%{idp.oidfed.resolve-entity.LocalMetadataPolicyStrategy:DefaultLocalMetadataPolicyStrategy}'.trim()}"/>
-
-    <bean id="MetadataPolicMergingyStrategy"
-        class="net.shibboleth.oidfed.metadata.policy.impl.DefaultFederationMetadataPolicyMergingStrategy"
-        p:metadataPolicyOperators-ref="#{'%{idp.oidfed.resolve-entity.MetadataPolicyOperatorsy:shibboleth.oidfed.StandardMetadataPolicyOperators}'.trim()}"/>
-
-    <bean id="DefaultLocalMetadataPolicyStrategy"
-        parent="shibboleth.Functions.Constant">
-        <constructor-arg name="target">
-            <util:map/>
-        </constructor-arg>
-    </bean>
-
-    <bean id="SelectTrustChain" class="net.shibboleth.oidfed.profile.impl.SelectTrustChain"
-        scope="prototype">
-        <property name="activationCondition">
-            <bean parent="shibboleth.Conditions.Expression"
-                c:expression="#input.ensureInboundMessageContext().containsSubcontext(T(net.shibboleth.oidfed.profile.context.RelyingPartyTrustChainContext))" />
-        </property>
-    </bean>
-
-    <bean id="ValidateSelectedTrustChain" class="net.shibboleth.idp.plugin.oidc.op.oidfed.profile.impl.ValidateSelectedTrustChain"
-        scope="prototype"
-        p:entityConfigurationCache-ref="shibboleth.oidfed.EntityConfigurationMetadataCache"/>
-
-    <bean id="ResolveTrustMarks" class="net.shibboleth.oidfed.profile.impl.ResolveTrustMarks"
-        scope="prototype"
-        p:trustChainCache-ref="#{'%{idp.oidfed.resolve-entity.TrustChainMetadataCache:shibboleth.oidfed.TrustChainMetadataCache}'.trim()}"
-        p:trustMarkClaimsValidationLookupStrategy="#{getObject('shibboleth.oidfed.TrustMarkClaimsValidationLookupStrategy') ?: getObject('DefaultTrustMarkClaimsValidationLookupStrategy')}"
-        p:delegatedTrustMarkClaimsValidationLookupStrategy="#{getObject('shibboleth.oidfed.DelegatedTrustMarkClaimsValidationLookupStrategy') ?: getObject('DefaultDelegatedTrustMarkClaimsValidationLookupStrategy')}"
-        p:trustEngine-ref="shibboleth.oidfed.DefaultEntityConfigurationTrustEngine"
-        p:delegationTrustEngine-ref="shibboleth.oidfed.DefaultDelegatedTrustMarkTrustEngine">
-        <property name="trustChainTrustMarksParsingStrategy">
-            <bean class="net.shibboleth.oidfed.profile.navigate.DefaultTrustChainTrustMarksParsingStrategy"
-                p:objectMapper-ref="shibboleth.oidfed.JWTPayloadJSONObjectMapper"/>
-        </property>
-        <property name="trustedTrustMarkIssuersLookupStrategy">
-            <bean class="net.shibboleth.oidfed.profile.navigate.DefaultTrustChainTrustedTrustMarkIssuersLookupStrategy"/>
-        </property>
-        <property name="trustedTrustMarkOwnersLookupStrategy">
-            <bean class="net.shibboleth.oidfed.profile.navigate.DefaultTrustChainTrustedTrustMarkOwnersLookupStrategy"/>
-        </property>
-    </bean>
-
-    <bean id="ValidateTrustMarks" class="net.shibboleth.oidfed.profile.impl.ValidateTrustMarks"
-        scope="prototype"
-        p:trustMarkStatusCache-ref="#{'%{idp.oidfed.resolve-entity.TrustMarkStatusMetadataCache:shibboleth.oidfed.TrustMarkStatusMetadataCache}'.trim()}">
-    </bean>
-
-    <bean id="PopulateResolveResponseSignatureSigningParameters"
-        class="net.shibboleth.oidc.profile.impl.PopulateJWTSignatureSigningParameters" scope="prototype"
-        c:strategy-ref="shibboleth.MessageContextLookup.Outbound"
-        p:securityParametersContextLookupStrategy-ref="ResolveResponseSecurityParametersContextLookupStrategy">
-        <property name="configurationLookupStrategy">
-            <bean lazy-init="true"
-                class="net.shibboleth.oidc.profile.config.navigate.JWTSignatureSigningConfigurationLookupFunction" />
-        </property>
-        <property name="signatureSigningParametersResolver">
-            <bean class="net.shibboleth.oidc.security.jose.impl.ClientInformationSignatureSigningParametersResolver">
-                <constructor-arg name="signatureAlgorithmLookupStrategy">
-                    <bean parent="shibboleth.Functions.Constant" c:target="" />
-                </constructor-arg>
-                <constructor-arg name="defaultAlgorithmValue" value="%{idp.oidfed.entity.sigalg:RS256}" />
-            </bean>
-        </property>
-    </bean>
-
-    <bean id="ResolveResponseSecurityParametersContextLookupStrategy" parent="shibboleth.Functions.Compose"
-            c:g-ref="shibboleth.oidc.ChildLookupOrCreate.JWTSecurityParameters"
-            c:f-ref="shibboleth.ChildLookup.RelyingParty" />
-
-    <bean id="ResolveResponseSecurityParametersCreationViaMessageContextStrategy" parent="shibboleth.Functions.Compose">
-        <constructor-arg name="g" ref="ResolveResponseSecurityParametersContextLookupStrategy" />
-        <constructor-arg name="f">
-            <bean parent="shibboleth.Functions.Expression" c:expression="#input.getParent()" />
-        </constructor-arg>
-    </bean>
-
-    <bean id="BuildResolveResponse"
-        class="net.shibboleth.idp.plugin.oidc.op.oidfed.profile.impl.BuildResolveEntityResponse" scope="prototype"
-        p:identifierGeneratorLookupStrategy-ref="shibboleth.oidc.DefaultIdentifierGenerationStrategy"
-        p:objectMapper-ref="#{'%{idp.oidc.logging.objectMapper:shibboleth.oidc.JSONObjectMapper}'.trim()}">
-        <property name="subjectLookupStrategy">
-            <bean parent="shibboleth.Functions.Expression"
-                c:expression="#input.ensureInboundMessageContext().getMessage().getSubject()" />
-        </property>    
-    </bean>
-
-    <bean id="SignResolveResponse" class="net.shibboleth.idp.profile.impl.WebFlowMessageHandlerAdaptor"
-            scope="prototype" c:executionDirection="OUTBOUND ">
-        <constructor-arg name="messageHandler">
-            <bean id="SignResolveResponseHandler"
-                class="net.shibboleth.oidc.security.impl.SignJWTHandler" scope="prototype" p:logName="Resolve Response"
-                p:securityParametersLookupStrategy-ref="ResolveResponseSecurityParametersCreationViaMessageContextStrategy"
-                p:typeHeader="resolve-response+jwt">
-                <property name="claimsToSignLookupStrategy">
-                     <bean
-                        class="net.shibboleth.oidfed.profile.impl.JWTClaimsSetFromEntityStatementLookupFunction" />
-                </property>
-                <property name="jwtUpdateConsumer">
-                    <bean
-                        class="net.shibboleth.oidfed.profile.impl.EntityStatementUpdateStrategy" />
-                </property>
-            </bean>
-        </constructor-arg>
-    </bean>
-
-    <bean id="FormOutboundMessage"
-        class="net.shibboleth.idp.plugin.oidc.op.oidfed.profile.impl.FormOutboundResolveEntityResponse" scope="prototype"
-        p:responseCache-ref="shibboleth.oidfed.ResolveEntityResponseMetadataCache" />
-
-    <bean id="BuildErrorResponseFromEvent"
-        class="net.shibboleth.idp.plugin.oidc.op.oidfed.profile.impl.BuildResolveEntityErrorResponseFromEvent" scope="prototype"
-        p:httpServletResponseSupplier-ref="shibboleth.HttpServletResponseSupplier"
-        p:mappedErrors="#{getObject('shibboleth.oidfed.resolve-entity.MappedErrors') ?: getObject('shibboleth.oidc.DefaultResolveEntityApiMappedErrors')}"
-        p:responseCache-ref="shibboleth.oidfed.ResolveEntityResponseMetadataCache">
-        <property name="eventContextLookupStrategy">
-            <bean class="net.shibboleth.idp.profile.context.navigate.WebFlowCurrentEventLookupFunction" />
-        </property>
-    </bean>
-
-</beans>
diff --git a/idp-oidfed-op-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidfed/resolve-entity/resolve-entity-flow.xml b/idp-oidfed-op-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidfed/resolve-entity/resolve-entity-flow.xml
deleted file mode 100644
index 38665e3..0000000
--- a/idp-oidfed-op-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidfed/resolve-entity/resolve-entity-flow.xml
+++ /dev/null
@@ -1,112 +0,0 @@
-<flow xmlns="http://www.springframework.org/schema/webflow"
-    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-    xsi:schemaLocation="http://www.springframework.org/schema/webflow http://www.springframework.org/schema/webflow/spring-webflow.xsd"
-    parent="oidc/abstract, oidc/metadata-lookup, oidfed/resolve-trust-chains">
-
-    <action-state id="InitializeMandatoryContexts">
-        <evaluate expression="InitializeProfileRequestContext" />
-        <evaluate expression="PopulateMetricContext" />
-        <evaluate expression="FlowStartPopulateAuditContext" />
-        <evaluate expression="InitializeOutboundMessageContext" />
-        <evaluate expression="'proceed'" />
-        
-        <transition on="proceed" to="DecodeMessage">
-            <set name="flowScope.transitionAfterDecode" value="'PostDecode'" />
-         </transition>
-    </action-state>
-
-    <action-state id="PostDecode">
-        <on-entry>
-            <set name="flowScope.skipOAuth2ClientAuth" value="opensamlProfileRequestContext.getInboundMessageContext().getMessage().getClientAuthentication() == null" />
-        </on-entry>
-        <evaluate expression="'proceed'"/>
-        <transition on="proceed" to="#{skipOAuth2ClientAuth ? 'SelectConfiguration' : 'DoMetadataLookup'}" />
-    </action-state>
-
-    <action-state id="SelectConfiguration">
-        <evaluate expression="InitializeRelyingPartyContext" />
-        <evaluate expression="SelectRelyingPartyConfiguration" />
-        <evaluate expression="SelectProfileConfiguration" />
-        <evaluate expression="CallInboundMessageHandler" />
-        <evaluate expression="PostLookupPopulateAuditContext" />
-        <evaluate expression="PopulateInboundInterceptContext" />
-        <evaluate expression="'proceed'" />
-        
-        <transition on="proceed" to="CheckInboundInterceptContext" />
-    </action-state>
-
-    <decision-state id="CheckInboundInterceptContext">
-        <if test="opensamlProfileRequestContext.ensureSubcontext(T(net.shibboleth.idp.profile.context.ProfileInterceptorContext)).getAvailableFlows().isEmpty()"
-            then="#{skipOAuth2ClientAuth ? 'ResumeAfterAuthentication' : 'AuthenticationSetup'}" else="DoInboundInterceptSubflow" />
-    </decision-state>
-
-    <subflow-state id="DoInboundInterceptSubflow" subflow="intercept">
-        <input name="calledAsSubflow" value="true" />
-        <transition on="proceed" to="#{skipOAuth2ClientAuth ? 'ResumeAfterAuthentication' : 'AuthenticationSetup'}" />
-    </subflow-state>
-
-    <action-state id="AuthenticationSetup">
-        <evaluate expression="CallInboundMessageHandler" />
-        <evaluate expression="InitializeAuthenticationContext" />
-        <evaluate expression="'proceed'" />
-        <transition on="proceed" to="DoAuthenticationSubflow" />
-    </action-state>
-
-    <subflow-state id="DoAuthenticationSubflow" subflow="authn">
-        <input name="calledAsSubflow" value="true" />
-        <input name="bypassSessionActions" value="true" />
-        <input name="potentialFlows" value="getActiveFlow().getApplicationContext().getBean('shibboleth.oidfed.resolver.PotentialFlows')" />
-        <transition on="proceed" to="ResumeAfterAuthentication" />
-        <transition on="RestartAuthentication" to="AuthenticationSetup" />
-    </subflow-state>
-
-    <!-- Authentication subflow happens here. -->
-
-    <action-state id="ResumeAfterAuthentication">
-        <evaluate expression="ValidateRequest" />
-        <evaluate expression="LookupCachedResolveEntityResponse" />
-        <evaluate expression="'proceed'" />
-        <transition on="CachedResponseFound" to="BuildResponseMessage" />
-        <transition on="proceed" to="ResolveTrustChains" />
-    </action-state>
-
-    <action-state id="ResolveTrustChains">
-        <evaluate expression="ResolveTrustChains" />
-        <evaluate expression="'proceed'" />
-        <transition on="proceed" to="SelectTrustChain" />
-    </action-state>
-
-    <action-state id="SelectTrustChain">
-        <evaluate expression="SelectTrustChain" />
-        <evaluate expression="ValidateSelectedTrustChain" />
-        <evaluate expression="ResolveTrustMarks" />
-        <evaluate expression="ValidateTrustMarks" />
-        <evaluate expression="'proceed'" />
-        <transition on="ReselectTrustChain" to="SelectTrustChain" />
-        <transition on="proceed" to="BuildResponse" />
-    </action-state>
-
-
-    <action-state id="BuildResponse">
-        <evaluate expression="PopulateResolveResponseSignatureSigningParameters" />
-        <evaluate expression="BuildResolveResponse" />
-        <evaluate expression="SignResolveResponse" />
-        <evaluate expression="'proceed'" />
-        
-        <transition on="proceed" to="BuildResponseMessage" />
-    </action-state>
-
-    <action-state id="HandleError">
-        <on-entry>
-            <evaluate
-                expression="opensamlProfileRequestContext.ensureSubcontext(T(net.shibboleth.idp.profile.context.SpringRequestContext)).setRequestContext(flowRequestContext)" />
-            <evaluate expression="LogEvent" />
-        </on-entry>
-        <evaluate expression="BuildErrorResponseFromEvent" />
-        <evaluate expression="'proceed'" />
-        <transition on="proceed" to="PopulateOutboundInterceptContext"/>
-    </action-state>
-
-    <bean-import resource="resolve-entity-beans.xml" />
-
-</flow>
\ No newline at end of file
diff --git a/idp-oidfed-op-impl/src/main/resources/META-INF/net/shibboleth/idp/service/relying-party/postconfig.xml b/idp-oidfed-op-impl/src/main/resources/META-INF/net/shibboleth/idp/service/relying-party/postconfig.xml
index 80ad2a6..042d770 100644
--- a/idp-oidfed-op-impl/src/main/resources/META-INF/net/shibboleth/idp/service/relying-party/postconfig.xml
+++ b/idp-oidfed-op-impl/src/main/resources/META-INF/net/shibboleth/idp/service/relying-party/postconfig.xml
@@ -48,15 +48,4 @@
         p:remoteTrustMarkValidation="%{idp.oidfed.op.explicitRegistration.remoteTrustMarkValidation:true}"
         p:tokenEndpointAuthMethods="%{idp.oidfed.op.explicitRegistration.tokenEndpointAuthMethods:client_secret_basic,client_secret_post,client_secret_jwt,private_key_jwt}"/>
 
-    <bean id="OIDFED.ResolveEntity" parent="AbstractOIDFederationProfile" lazy-init="true"
-        class="net.shibboleth.oidfed.profile.config.impl.DefaultOIDFederationResolveEntityProfileConfiguration"
-        p:issuer-ref="shibboleth.oidc.issuer"
-        p:tokenEndpointAuthMethods="%{idp.oidfed.resolve-entity.endpointAuthMethods:private_key_jwt}"
-        p:claimsValidator="#{getObject('DefaultJWTClaimsValidator')}"
-        p:useTargetedEndpointAsJWTAudience="%{idp.oidfed.resolve-entity.targetedEndpointAsJWTAudience:false}"
-        p:requireSingleJWTAudience="%{idp.oidfed.resolve-entity.requireSingleJWTAudience:true}"/>
-
-    <bean id="RelyingPartyByTrustAnchor" abstract="true" parent="RelyingParty"
-        class="net.shibboleth.idp.plugin.oidc.op.oidfed.profile.context.RelyingPartyConfigurationSupport" factory-method="byTrustAnchor" />
-
 </beans>
diff --git a/idp-oidfed-op-impl/src/main/resources/net/shibboleth/idp/plugin/oidc/op/oidfed/conf/oidfed/oidfed-op.properties b/idp-oidfed-op-impl/src/main/resources/net/shibboleth/idp/plugin/oidc/op/oidfed/conf/oidfed/oidfed-op.properties
index 303bf80..40f23fe 100644
--- a/idp-oidfed-op-impl/src/main/resources/net/shibboleth/idp/plugin/oidc/op/oidfed/conf/oidfed/oidfed-op.properties
+++ b/idp-oidfed-op-impl/src/main/resources/net/shibboleth/idp/plugin/oidc/op/oidfed/conf/oidfed/oidfed-op.properties
@@ -62,25 +62,3 @@ idp.oidfed.op.explicitRegistration.FederationPolicyConstraints = shibboleth.oidf
 idp.service.logging.oidfedconfig = OIDFED.SignedKeyset
 idp.oidfed.op.cache.signedKeyset.minRefreshDelay = PT1S
 idp.oidfed.op.cache.signedKeyset.maxRefreshDelay = PT30S
-
-# resolve-entity-beans, TODO: move these to oidfed-common once the feature is moved there
-#idp.oidfed.resolve-entity.authn.flows = OAuth2Client
-
-
-#idp.service.logging.oidfedresolve = OIDFED.ResolveEntity
-#idp.oidfed.requestParser.ResolveEntityRequest =
-#idp.oidfed.cache.resolveEntity.minRefreshDelay = PT1S
-#idp.oidfed.cache.resolveEntity.maxRefreshDelay = PT30S
-#idp.oidfed.resolve-entity.LocalTrustAnchorsMetadataCache = shibboleth.oidfed.LocalTrustAnchorsMetadataCache
-#idp.oidfed.resolve-entity.MetadataPolicyOperatorsy = shibboleth.oidfed.StandardMetadataPolicyOperators
-#idp.oidfed.resolve-entity.MetadataPolicMergingyStrategy = MetadataPolicMergingyStrategy
-#idp.oidfed.resolve-entity.LocalMetadataPolicyStrategy = DefaultLocalMetadataPolicyStrategy
-#idp.oidfed.resolve-entity.TrustChainMetadataCache = shibboleth.oidfed.TrustChainMetadataCache
-#idp.oidfed.resolve-entity.TrustMarkStatusMetadataCache = shibboleth.oidfed.TrustMarkStatusMetadataCache
-#idp.oidfed.entity.sigalg = RS256
-#idp.oidfed.resolve-entity.automaticRegistrationCondition = shibboleth.Conditions.TRUE
-
-# relying-party/postconfig.xml
-#idp.oidfed.resolve-entity.endpointAuthMethods = private_key_jwt
-#idp.oidfed.resolve-entity.targetedEndpointAsJWTAudience = false
-#idp.oidfed.resolve-entity.requireSingleJWTAudience = true
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
deleted file mode 100644
index c6bde81..0000000
--- a/idp-oidfed-op-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/oidfed/ResolveEntityFlowTest.java
+++ /dev/null
@@ -1,371 +0,0 @@
-/*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package net.shibboleth.idp.plugin.oidc.op.profile.flow.oidfed;
-
-import java.io.IOException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.time.Instant;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.opensaml.storage.StorageService;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Qualifier;
-import org.springframework.webflow.executor.FlowExecutionResult;
-import org.testng.Assert;
-import org.testng.annotations.Test;
-
-import com.fasterxml.jackson.databind.ObjectMapper;
-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 com.nimbusds.oauth2.sdk.Scope;
-import com.nimbusds.openid.connect.sdk.rp.OIDCClientMetadata;
-
-import net.shibboleth.oidc.profile.messaging.JSONErrorResponse;
-import net.shibboleth.oidfed.messaging.impl.ResolveEntityResponse;
-import net.shibboleth.oidfed.metadata.EntityStatement;
-import net.shibboleth.oidfed.metadata.impl.SubordinateStatementImpl;
-import net.shibboleth.oidfed.testing.FederationJwtSupport;
-import net.shibboleth.shared.collection.CollectionSupport;
-import net.minidev.json.JSONObject;
-
-/**
- * Flow tests for the OpenID federation resolve entity flow.
- */
-public class ResolveEntityFlowTest extends AbstractFederationFlowTest {
-    
-    public static final String FLOW_ID = "oidfed/resolve-entity";
-
-    @Autowired
-    @Qualifier("shibboleth.StorageService")
-    StorageService storageService;
-
-    public ResolveEntityFlowTest() {
-        super(FLOW_ID);
-    }
-    
-    @Test
-    public void testInvalidMethod() throws Exception {
-        setJsonRequest("POST", "{}");
-        final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
-        assertErrorCode(result, "invalid_request");
-    }
-
-    @Test
-    public void testNoContentType() throws Exception {
-        request.setMethod("GET");
-        request.setQueryString("sub=mockClientId&trust_anchor=" + anchorId + "&entity_type=openid_relying_party");
-        final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
-        assertErrorCode(result, "invalid_request");
-    }
-
-    @Test
-    public void testInvalidSubject() throws Exception {
-        request.setMethod("GET");
-        request.setContentType("application/x-www-form-urlencoded");
-        request.setQueryString("sub=mockClientId&trust_anchor=" + anchorId + "&entity_type=openid_relying_party");
-        final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
-        assertErrorCode(result, "invalid_subject");
-    }
-
-    @Test
-    public void testUntrustedAnchor() throws Exception {
-        request.setMethod("GET");
-        final String clientId = uniqueClientId();
-        rpConfigureMockHttpClient(clientId);
-        request.setContentType("application/x-www-form-urlencoded");
-        request.setQueryString("sub=" + clientId + "&trust_anchor=mockAnchors&entity_type=openid_relying_party");
-        final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
-        assertErrorCode(result, "invalid_trust_anchor");
-    }
-
-    @Test
-    public void testRPWithTrustedTrustAnchor() throws Exception {
-        request.setMethod("GET");
-        final String clientId = uniqueClientId();
-        rpConfigureMockHttpClient(clientId);
-        request.setContentType("application/x-www-form-urlencoded");
-        request.setQueryString("sub=" + clientId + "&trust_anchor=" + anchorId + "&entity_type=openid_relying_party");
-        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(), clientId);
-        Assert.assertNotNull(response.getJWTClaimsSet().getClaim("metadata"));
-        Assert.assertNull(response.getJWTClaimsSet().getClaim("authority_hints"));
-    }
-
-    @Test
-    public void testRPWithTrustedTrustAnchor_validTrustMark() throws Exception {
-        request.setMethod("GET");
-        final String clientId = uniqueClientId();
-        final String trustMark = FederationJwtSupport.trustMark(JWSAlgorithm.RS256, trustMarkIssuerKey, trustMarkIssuerId,
-                clientId, "https://example.org/email-allowing-trust-mark", Instant.now().plusSeconds(300)).serialize();
-        final OIDCClientMetadata metadata = new OIDCClientMetadata();
-        metadata.setRedirectionURI(new URI(redirectUri));
-        metadata.setJWKSet(new JWKSet(rpKey.toPublicJWK()));
-        final String rpEntityConfiguration = rpEntityConfiguration(clientId, metadata, List.of(Map.of(
-                "trust_mark_type", "https://example.org/email-allowing-trust-mark",
-                "trust_mark", trustMark)), leafKey);
-        rpConfigureMockHttpClient(clientId, rpEntityConfiguration);
-        try {
-            mapResponse(entityConfigurationUrl(trustMarkIssuerId),
-                    mockResponse(trustMarkIssuerConfiguration(trustMarkIssuerId)));
-            mapResponse(subordinateStatementUrl(anchorFetchEndpoint, trustMarkIssuerId),
-                    mockResponse(subordinateStatement(trustMarkIssuerId,
-                            Map.of("federation_entity", CollectionSupport.emptyMap()), trustMarkIssuerKey)));
-            mapResponse(trustMarkStatusEndpoint, mockResponse(200, "application/trust-mark-status-response+jwt",
-                    trustMarkStatusResponse(trustMarkIssuerId, trustMark, "active", trustMarkIssuerKey)));
-        } catch (UnsupportedOperationException | IOException e) {
-            Assert.fail("Could not initialize mock HTTP client", e);
-        }
-        request.setContentType("application/x-www-form-urlencoded");
-        request.setQueryString("sub=" + clientId + "&trust_anchor=" + anchorId + "&entity_type=openid_relying_party");
-        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(), clientId);
-        Assert.assertNotNull(response.getJWTClaimsSet().getClaim("metadata"));
-        Assert.assertNull(response.getJWTClaimsSet().getClaim("authority_hints"));
-        final Map<String,Object> trustMarks = response.getJWTClaimsSet().getJSONObjectClaim("trust_marks");
-        Assert.assertNotNull(trustMarks, "Could not find trust marks for client " + clientId);
-        Assert.assertEquals(trustMarks.size(), 1);
-        Assert.assertEquals(trustMarks.get("https://example.org/email-allowing-trust-mark"), trustMark);
-    }
-
-    @Test
-    public void testRPWithTrustedTrustAnchor_subordinateKeyNotMatchingEntityConfiguration() throws Exception {
-        request.setMethod("GET");
-        final String clientId = uniqueClientId();
-        rpConfigureMockHttpClient(clientId, initializeNewJwk("RSA", 2048, "mockNewLeafKey"));
-        request.setContentType("application/x-www-form-urlencoded");
-        request.setQueryString("sub=" + clientId + "&trust_anchor=" + anchorId + "&entity_type=openid_relying_party");
-        final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
-        assertErrorCode(result, "invalid_request");
-        assertErrorDescriptionContains(result, "NoTrustChainsResolved");
-    }
-
-    @Test
-    public void testRPWithTrustedTrustAnchorInvalidMetadata() throws Exception {
-        request.setMethod("GET");
-        final String clientId = uniqueClientId();
-        rpConfigureMockHttpClient(clientId, new JSONObject(Map.of("response_types", "invalid")));
-        request.setContentType("application/x-www-form-urlencoded");
-        request.setQueryString("sub=" + clientId + "&trust_anchor=" + anchorId + "&entity_type=openid_relying_party");
-        final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
-        assertErrorCode(result, "invalid_metadata");
-    }
-
-    @Test
-    public void testOPWithTrustedTrustAnchor() throws Exception {
-        request.setMethod("GET");
-        final String entityId = uniqueClientId();
-        opConfigureMockHttpClient(entityId);
-        request.setContentType("application/x-www-form-urlencoded");
-        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"));
-    }
-
-    @Test
-    public void testOPWithTrustedTrustAnchorInvalidMetadata() throws Exception {
-        request.setMethod("GET");
-        final String entityId = uniqueClientId();
-        opConfigureMockHttpClient(entityId, new JSONObject(Map.of("issuer", List.of("unexpected", "values"))));
-        request.setContentType("application/x-www-form-urlencoded");
-        request.setQueryString("sub=" + entityId + "&trust_anchor=" + anchorId + "&entity_type=openid_provider");
-        final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
-        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 ObjectMapper objectMapper = payloadObjectMapper;
-        assert objectMapper != null;
-        final SignedJWT jwt = FederationJwtSupport.entityStatement(JWSAlgorithm.RS256, trustedAnchorKey, claimsSet);
-        assert jwt != null;
-        final EntityStatement<?> subordinateStatement = SubordinateStatementImpl.parse(jwt, objectMapper);
-        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.setContentType("application/x-www-form-urlencoded");
-        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"));
-    }
-
-    @Test
-    public void testRPWithTrustedTrustAnchor_jwtAuth_successWithLeafKey() throws Exception {
-        request.setMethod("POST");
-        final String requestingClientId = uniqueClientId();
-        final String clientId = uniqueClientId();
-        final JWTClaimsSet claimsSet = new JWTClaimsSet.Builder()
-                .issuer(requestingClientId)
-                .subject(requestingClientId)
-                .audience(issuer)
-                .expirationTime(Date.from(Instant.now().plusSeconds(600)))
-                .jwtID(idGenerator.generateIdentifier())
-                .build();
-
-        final SignedJWT jwt = createPrivateKeyJWT(claimsSet, leafKey.toRSAKey().toRSAPrivateKey());
-        final Map<String, String> requestParams = new HashMap<>();
-        requestParams.put("sub", clientId);
-        requestParams.put("trust_anchor", anchorId);
-        requestParams.put("entity_type", "openid_relying_party");
-        populateClientAssertionParams(requestParams, jwt);
-        rpConfigureMockHttpClient(requestingClientId);
-        rpConfigureMockHttpClient(clientId);
-        request.setContentType("application/x-www-form-urlencoded");
-        setHttpFormRequest(request, "POST", requestParams);
-        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(), clientId);
-        Assert.assertNotNull(response.getJWTClaimsSet().getClaim("metadata"));
-        Assert.assertNull(response.getJWTClaimsSet().getClaim("authority_hints"));
-    }
-
-    @Test
-    public void testRPWithTrustedTrustAnchor_basicAuth_successForLocalClient() throws Exception {
-        request.setMethod("POST");
-        final String registeredClientId = "localResolveEntityClient";
-        final String secret = "mockClientSecret";
-        storeMetadata(storageService, registeredClientId, secret, Scope.parse("openid"), redirectUri);
-        final String clientId = uniqueClientId();
-        final Map<String, String> requestParams = new HashMap<>();
-        requestParams.put("sub", clientId);
-        requestParams.put("trust_anchor", anchorId);
-        requestParams.put("entity_type", "openid_relying_party");
-        setBasicAuth(registeredClientId, secret);
-
-        rpConfigureMockHttpClient(clientId);
-        request.setContentType("application/x-www-form-urlencoded");
-        setHttpFormRequest(request, "POST", requestParams);
-        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(), clientId);
-        Assert.assertNotNull(response.getJWTClaimsSet().getClaim("metadata"));
-        Assert.assertNull(response.getJWTClaimsSet().getClaim("authority_hints"));
-    }
-
-    @Test
-    public void testRPWithTrustedTrustAnchor_basicAuth_failForLocalClientWithDefaultConfig() throws Exception {
-        request.setMethod("POST");
-        final String registeredClientId = "localDefaultClient";
-        final String secret = "mockClientSecret";
-        storeMetadata(storageService, registeredClientId, secret, Scope.parse("openid"), redirectUri);
-        final String clientId = uniqueClientId();
-        final Map<String, String> requestParams = new HashMap<>();
-        requestParams.put("sub", clientId);
-        requestParams.put("trust_anchor", anchorId);
-        requestParams.put("entity_type", "openid_relying_party");
-        setBasicAuth(registeredClientId, secret);
-
-        rpConfigureMockHttpClient(clientId);
-        request.setContentType("application/x-www-form-urlencoded");
-        setHttpFormRequest(request, "POST", requestParams);
-        final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
-        assertErrorCode(result, "unauthorized_client");
-    }
-
-    @Test
-    public void testRPWithTrustedTrustAnchor_basicAuth_failWithGet() throws Exception {
-        request.setMethod("GET");
-        final String registeredClientId = "localResolveEntityClient";
-        final String secret = "mockClientSecret";
-        storeMetadata(storageService, registeredClientId, secret, Scope.parse("openid"), redirectUri);
-        final String clientId = uniqueClientId();
-        request.setContentType("application/x-www-form-urlencoded");
-        request.setQueryString("sub=" + clientId + "&trust_anchor=" + anchorId + "&entity_type=openid_relying_party");
-        setBasicAuth(registeredClientId, secret);
-
-        rpConfigureMockHttpClient(clientId);
-        request.setContentType("application/x-www-form-urlencoded");
-        final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
-        assertErrorCode(result, "invalid_request");
-    }
-
-    @Test
-    public void testRPWithTrustedTrustAnchor_jwtAuth_failWithRpfKey() throws Exception {
-        request.setMethod("POST");
-        final String clientId = uniqueClientId();
-        final JWTClaimsSet claimsSet = new JWTClaimsSet.Builder()
-                .issuer(clientId)
-                .subject(clientId)
-                .audience(issuer)
-                .expirationTime(Date.from(Instant.now().plusSeconds(600)))
-                .jwtID(idGenerator.generateIdentifier())
-                .build();
-
-        final SignedJWT jwt = createPrivateKeyJWT(claimsSet, rpKey.toRSAKey().toRSAPrivateKey());
-        final Map<String, String> requestParams = new HashMap<>();
-        requestParams.put("sub", clientId);
-        requestParams.put("trust_anchor", anchorId);
-        requestParams.put("entity_type", "openid_relying_party");
-        populateClientAssertionParams(requestParams, jwt);
-        rpConfigureMockHttpClient(clientId);
-        request.setContentType("application/x-www-form-urlencoded");
-        setHttpFormRequest(request, "POST", requestParams);
-        final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
-        assertErrorCode(result, "invalid_client");
-    }
-
-    protected JSONErrorResponse parseErrorResponse(final FlowExecutionResult result) {
-        final Response response = parseResponse(result);
-        Assert.assertTrue(response instanceof JSONErrorResponse);
-        return (JSONErrorResponse) response;
-    }
-
-}
diff --git a/idp-oidfed-op-impl/src/test/resources/net/shibboleth/idp/module/conf/relying-party.xml b/idp-oidfed-op-impl/src/test/resources/net/shibboleth/idp/module/conf/relying-party.xml
index c3148c8..a91b77f 100644
--- a/idp-oidfed-op-impl/src/test/resources/net/shibboleth/idp/module/conf/relying-party.xml
+++ b/idp-oidfed-op-impl/src/test/resources/net/shibboleth/idp/module/conf/relying-party.xml
@@ -41,7 +41,6 @@
                 <ref bean="OIDC.Configuration" />
                 <bean parent="OIDFED.Configuration" p:cachedSuccessResponseLifetime="PT2S" />
                 <bean parent="OIDFED.Keyset" p:cachedSuccessResponseLifetime="PT2S" />
-                <bean parent="OIDFED.ResolveEntity" />
             </list>
         </property>
     </bean>
@@ -74,15 +73,6 @@
                     <bean parent="OAUTH2.Token.MDDriven" p:tokenEndpointAuthMethods="client_secret_basic,client_secret_post,client_secret_jwt,private_key_jwt,none"/>
                     <bean parent="OAUTH2.PAR.MDDriven" p:tokenEndpointAuthMethods="private_key_jwt,none"/>
                     <ref bean="OIDC.UserInfo.MDDriven" />
-                    <!-- Enabled for federation-authenticated clients -->
-                    <bean parent="OIDFED.ResolveEntity" />
-                </list>
-            </property>
-        </bean>
-        <bean parent="RelyingPartyByName" c:relyingPartyIds="localResolveEntityClient">
-            <property name="profileConfigurations">
-                <list>
-                    <bean parent="OIDFED.ResolveEntity" p:tokenEndpointAuthMethods="client_secret_basic"/>
                 </list>
             </property>
         </bean>

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


More information about the commits mailing list