[java-idp-plugin-oidc-rp] branch main updated: Add basic framework for RequestObject encryption. Cleanup actions

Phil Smart philip.smart at jisc.ac.uk
Tue Jul 12 13:58:29 UTC 2022


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

philsmart pushed a commit to branch main
in repository java-idp-plugin-oidc-rp.

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

The following commit(s) were added to refs/heads/main by this push:
     new 2f21443  Add basic framework for RequestObject encryption. Cleanup actions
2f21443 is described below

commit 2f21443345a4bf780cda74ddc62a621698d1260a
Author: Phil Smart <philip.smart at jisc.ac.uk>
AuthorDate: Tue Jul 12 14:58:21 2022 +0100

    Add basic framework for RequestObject encryption. Cleanup actions
    
    The encryption support is nowhere near complete.
---
 .../logic/EncryptRequestObjectPredicate.java       |  45 ++++
 ...bjectEncryptionConfigurationLookupFunction.java |  96 +++++++
 .../rp/context/OutboundMessageHandlerContext.java  |  54 +---
 .../AbstractOIDCAuthenticationRequestAction.java   |   5 +-
 ...> AddAuthenticationContextClassReferences.java} |   5 +-
 ...opulateEndpointURI.java => AddEndpointURI.java} |   4 +-
 ...ompt.java => AddForceAuthenticationPrompt.java} |   7 +-
 .../rp/impl/{PopulateNonce.java => AddNonce.java}  |   9 +-
 .../rp/{messaging => }/impl/AddRedirectURI.java    |  64 +++--
 ...ypeAndMode.java => AddResponseTypeAndMode.java} |  57 +---
 .../impl/{PopulateScopes.java => AddScopes.java}   |   4 +-
 .../oidc/rp/impl/AuthorizationController.java      |   5 +-
 .../authn/oidc/rp/impl/BuildRequestObject.java     |  56 ++--
 .../rp/impl/PopulateJWTEncryptionParameters.java   | 294 +++++++++++++++++++++
 ...yingPartyProxyEncryptionParametersResolver.java |  68 +++++
 ...RelyingPartyProxySigningParametersResolver.java |   8 +-
 .../oidc-relying-party-authn-beans.xml             | 128 +++++----
 .../oidc-relying-party-authn-flow.xml              |  16 +-
 .../idp/service/relying-party/postconfig.xml       |  57 +++-
 .../authn/oidc/rp/conf/authn/oidc-rp.properties    |   3 +
 ...deTest.java => AddResponseTypeAndModeTest.java} |   6 +-
 .../oidc/rp/impl/AuthorizationControllerTest.java  |  16 +-
 .../plugin/authn/oidc/rp/impl/OIDCRPFlowTest.java  |  67 ++---
 .../resources/conf/test-relying-party-system.xml   |   3 +-
 24 files changed, 794 insertions(+), 283 deletions(-)

diff --git a/idp-oidc-rp-api/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/config/logic/EncryptRequestObjectPredicate.java b/idp-oidc-rp-api/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/config/logic/EncryptRequestObjectPredicate.java
new file mode 100644
index 0000000..a2577a5
--- /dev/null
+++ b/idp-oidc-rp-api/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/config/logic/EncryptRequestObjectPredicate.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements.  See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You 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.authn.oidc.rp.config.logic;
+
+import javax.annotation.Nullable;
+
+import org.opensaml.profile.context.ProfileRequestContext;
+
+import net.shibboleth.idp.profile.config.ProfileConfiguration;
+import net.shibboleth.idp.profile.context.RelyingPartyContext;
+import net.shibboleth.idp.profile.logic.AbstractRelyingPartyPredicate;
+import net.shibboleth.oidc.profile.config.OIDCAuthorizationConfiguration;
+
+/** A predicate that determines if the RequestObject JWT should be encrypted based on the profile configuration.*/
+public class EncryptRequestObjectPredicate extends AbstractRelyingPartyPredicate {
+
+    @Override
+    public boolean test(@Nullable final ProfileRequestContext input) {
+        
+        final RelyingPartyContext rpc = getRelyingPartyContextLookupStrategy().apply(input);
+        if (rpc != null) {
+            final ProfileConfiguration pc = rpc.getProfileConfig();
+            if (pc instanceof OIDCAuthorizationConfiguration) {
+                return ((OIDCAuthorizationConfiguration) pc).isEncryptRequestObject(input);
+            }
+        }
+        return false;
+    }
+
+}
diff --git a/idp-oidc-rp-api/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/config/navigate/RequestObjectEncryptionConfigurationLookupFunction.java b/idp-oidc-rp-api/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/config/navigate/RequestObjectEncryptionConfigurationLookupFunction.java
new file mode 100644
index 0000000..2c78b5c
--- /dev/null
+++ b/idp-oidc-rp-api/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/config/navigate/RequestObjectEncryptionConfigurationLookupFunction.java
@@ -0,0 +1,96 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements.  See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You 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.authn.oidc.rp.config.navigate;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.annotation.Nullable;
+
+import org.opensaml.profile.context.ProfileRequestContext;
+import org.opensaml.xmlsec.EncryptionConfiguration;
+import org.opensaml.xmlsec.SignatureSigningConfiguration;
+
+import com.nimbusds.jwt.SignedJWT;
+
+import net.shibboleth.idp.profile.config.ProfileConfiguration;
+import net.shibboleth.idp.profile.config.SecurityConfiguration;
+import net.shibboleth.idp.profile.context.RelyingPartyContext;
+import net.shibboleth.idp.profile.context.navigate.AbstractRelyingPartyLookupFunction;
+import net.shibboleth.idp.relyingparty.RelyingPartyConfigurationResolver;
+import net.shibboleth.oidc.profile.config.OIDCSecurityConfiguration;
+import net.shibboleth.oidc.security.SignatureValidationConfiguration;
+
+/**
+ * A function that returns an {@link EncryptionConfiguration} list for request object encryption by way
+ * of various lookup strategies. 
+ * 
+ * <p>
+ * If a specific setting is unavailable, a null value is returned.
+ * </p>
+ */
+public class RequestObjectEncryptionConfigurationLookupFunction 
+            extends AbstractRelyingPartyLookupFunction<List<EncryptionConfiguration>> {
+
+    /** A resolver for default security configurations. */
+    @Nullable
+    private RelyingPartyConfigurationResolver rpResolver;
+
+    /**
+     * Set the resolver for default security configurations.
+     * 
+     * @param resolver the resolver to use
+     */
+    public void setRelyingPartyConfigurationResolver(@Nullable final RelyingPartyConfigurationResolver resolver) {
+        rpResolver = resolver;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    @Nullable
+    public List<EncryptionConfiguration> apply(@Nullable final ProfileRequestContext input) {
+
+        final List<EncryptionConfiguration> configs = new ArrayList<>();
+
+        final RelyingPartyContext rpc = getRelyingPartyContextLookupStrategy().apply(input);
+        if (rpc != null) {
+            final ProfileConfiguration pc = rpc.getProfileConfig();
+            if (pc != null && pc.getSecurityConfiguration(input) instanceof OIDCSecurityConfiguration
+                    && ((OIDCSecurityConfiguration) pc.getSecurityConfiguration(input))
+                            .getEncryptionConfiguration() != null) {
+                configs.add(((OIDCSecurityConfiguration) pc.getSecurityConfiguration(input))
+                        .getEncryptionConfiguration());
+            }
+        }
+
+        // Check for a per-profile default (relying party independent) config.
+        if (input != null && rpResolver != null) {
+            final SecurityConfiguration defaultConfig =
+                    rpResolver.getDefaultSecurityConfiguration(input.getProfileId());
+            if (defaultConfig instanceof OIDCSecurityConfiguration
+                    && ((OIDCSecurityConfiguration) defaultConfig)
+                    .getEncryptionConfiguration() != null) {
+                configs.add(
+                        ((OIDCSecurityConfiguration) defaultConfig).getEncryptionConfiguration());
+            }
+        }
+        // TODO: Support for Global Default configuration?
+        return configs;
+    }
+}
+
diff --git a/idp-oidc-rp-api/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/context/OutboundMessageHandlerContext.java b/idp-oidc-rp-api/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/context/OutboundMessageHandlerContext.java
index 562c001..f39269e 100644
--- a/idp-oidc-rp-api/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/context/OutboundMessageHandlerContext.java
+++ b/idp-oidc-rp-api/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/context/OutboundMessageHandlerContext.java
@@ -19,40 +19,27 @@ package net.shibboleth.idp.plugin.authn.oidc.rp.context;
 
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
 
 import org.opensaml.messaging.context.BaseContext;
 
 import net.shibboleth.utilities.java.support.logic.Constraint;
 
 /** 
- * A context to stash HTTP request/response controller parameters for use by message handlers.
+ * A context to stash controller parameters for use by message handlers.
  * For example, the OIDC RP preEncodeMessageHandlers.
  */
 public class OutboundMessageHandlerContext extends BaseContext {
     
-    /** The Http servlet request.*/
-    @Nullable private HttpServletRequest servletRequest;
-    
-    /** The Http servlet response.*/
-    @Nullable private HttpServletResponse servletResponse;
-    
     /** The spring webflow key.*/
     @Nullable private String webflowKey;
 
     /**
      * Constructor.
      *
-     * @param request the servlet request
-     * @param response the servlet response
      * @param key the swf key
      */
-    public OutboundMessageHandlerContext(@Nonnull final HttpServletRequest request, 
-            @Nonnull final HttpServletResponse response, @Nonnull final String key) {
-        super();
-        servletRequest = Constraint.isNotNull(request, "Http Servlet Request can not be null");
-        servletResponse = Constraint.isNotNull(response, "Http Servlet Response can not be null");
+    public OutboundMessageHandlerContext(@Nonnull final String key) {
+        super();       
         webflowKey = Constraint.isNotNull(key, "Spring Webflow Key can not be null");
     }
     
@@ -61,41 +48,6 @@ public class OutboundMessageHandlerContext extends BaseContext {
         // Do nothing
     }
     
-    /**
-     * Set the Http servlet request.
-     * @param request
-     */
-    public void setServletRequest(@Nonnull final HttpServletRequest request) {
-        servletRequest = Constraint.isNotNull(request, "Http Servlet Request can not be null");
-    }
-
-    /**
-     * Get the Http servlet request.
-     * 
-     * @return Returns the servletRequest.
-     */
-    @Nullable public HttpServletRequest getServletRequest() {
-        return servletRequest;
-    }
-    
-    /**
-     * Set the Http servlet response.
-     * 
-     * @param response the servlet response
-     */
-    public void setServletResponse(@Nonnull final HttpServletResponse response) {
-        servletResponse = Constraint.isNotNull(response, "Http Servlet Response can not be null");
-    }
-
-    /**
-     * Get the Http servlet response.
-     * 
-     * @return Returns the servletResponse.
-     */
-    @Nullable public HttpServletResponse getServletResponse() {
-        return servletResponse;
-    }
-    
     /**
      * Set the Spring Webflow execution key.
      *  
diff --git a/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/AbstractOIDCAuthenticationRequestAction.java b/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/AbstractOIDCAuthenticationRequestAction.java
index 9cb40ec..fd7e34d 100644
--- a/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/AbstractOIDCAuthenticationRequestAction.java
+++ b/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/AbstractOIDCAuthenticationRequestAction.java
@@ -80,9 +80,10 @@ abstract class AbstractOIDCAuthenticationRequestAction extends AbstractAuthentic
     }
     
     /**
-     * Set lookup strategy for relying party context.
+     * Set the strategy used to locate the {@link RelyingPartyContext} associated with a given
+     * {@link ProfileRequestContext}.
      * 
-     * @param strategy  lookup strategy
+     * @param strategy lookup strategy
      */
     public void setRelyingPartyContextLookupStrategy(
             @Nonnull final Function<ProfileRequestContext,RelyingPartyContext> strategy) {
diff --git a/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/PopulateACRs.java b/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/AddAuthenticationContextClassReferences.java
similarity index 95%
rename from idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/PopulateACRs.java
rename to idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/AddAuthenticationContextClassReferences.java
index acd439c..a526704 100644
--- a/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/PopulateACRs.java
+++ b/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/AddAuthenticationContextClassReferences.java
@@ -19,7 +19,6 @@ package net.shibboleth.idp.plugin.authn.oidc.rp.impl;
 
 import java.security.Principal;
 import java.util.List;
-import java.util.Set;
 import java.util.stream.Collectors;
 
 import javax.annotation.Nonnull;
@@ -38,10 +37,10 @@ import net.shibboleth.oidc.authn.principal.AuthenticationContextClassReferencePr
  * An action that adds any authentication context class references from the those derived from the
  * profile config - which may be proxied and mapped from the upstream request.
  */
-public class PopulateACRs extends AbstractOIDCAuthenticationRequestAction {
+public class AddAuthenticationContextClassReferences extends AbstractOIDCAuthenticationRequestAction {
     
     /** Class logger. */
-    @Nonnull private final Logger log = LoggerFactory.getLogger(PopulateACRs.class);
+    @Nonnull private final Logger log = LoggerFactory.getLogger(AddAuthenticationContextClassReferences.class);
     
     @Override
     protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext,
diff --git a/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/PopulateEndpointURI.java b/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/AddEndpointURI.java
similarity index 94%
rename from idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/PopulateEndpointURI.java
rename to idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/AddEndpointURI.java
index 4929dba..eb61079 100644
--- a/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/PopulateEndpointURI.java
+++ b/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/AddEndpointURI.java
@@ -29,10 +29,10 @@ import net.shibboleth.idp.authn.context.AuthenticationContext;
  * An action that adds the authorization endpoint URI from the providers metadata 
  * to the under constructions authentication request.
  */
-public class PopulateEndpointURI extends AbstractOIDCAuthenticationRequestAction {
+public class AddEndpointURI extends AbstractOIDCAuthenticationRequestAction {
     
     /** Class logger. */
-    @Nonnull private final Logger log = LoggerFactory.getLogger(PopulateEndpointURI.class);
+    @Nonnull private final Logger log = LoggerFactory.getLogger(AddEndpointURI.class);
     
     @Override
     protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext,
diff --git a/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/PopulateForceAuthenticationPrompt.java b/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/AddForceAuthenticationPrompt.java
similarity index 90%
rename from idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/PopulateForceAuthenticationPrompt.java
rename to idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/AddForceAuthenticationPrompt.java
index ab75c82..d184761 100644
--- a/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/PopulateForceAuthenticationPrompt.java
+++ b/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/AddForceAuthenticationPrompt.java
@@ -31,12 +31,13 @@ import net.shibboleth.idp.authn.AuthnEventIds;
 import net.shibboleth.idp.authn.context.AuthenticationContext;
 
 /** 
- * An action that set the Prompt parameter to 'Prompt' if force authn was requested by the upstream SP.
+ * An action that sets the 'prompt' parameter to 'login' if force authn was requested by the upstream SP - is
+ * is overridden in the profile config.
  */
-public class PopulateForceAuthenticationPrompt extends AbstractOIDCAuthenticationRequestAction {
+public class AddForceAuthenticationPrompt extends AbstractOIDCAuthenticationRequestAction {
     
     /** Class logger. */
-    @Nonnull private final Logger log = LoggerFactory.getLogger(PopulateForceAuthenticationPrompt.class);
+    @Nonnull private final Logger log = LoggerFactory.getLogger(AddForceAuthenticationPrompt.class);
     
     @Override
     protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext,
diff --git a/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/PopulateNonce.java b/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/AddNonce.java
similarity index 89%
rename from idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/PopulateNonce.java
rename to idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/AddNonce.java
index 30df967..2022bde 100644
--- a/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/PopulateNonce.java
+++ b/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/AddNonce.java
@@ -32,18 +32,19 @@ import net.shibboleth.utilities.java.support.component.ComponentSupport;
 import net.shibboleth.utilities.java.support.logic.Constraint;
 
 /** 
- * An action that adds the nonce from a lookup strategy to the under constructions authentication request.
+ * An action that adds a nonce from a lookup strategy to the under constructions authentication request.
  */
-public class PopulateNonce extends AbstractOIDCAuthenticationRequestAction {
+public class AddNonce extends AbstractOIDCAuthenticationRequestAction {
     
     /** Class logger. */
-    @Nonnull private final Logger log = LoggerFactory.getLogger(PopulateNonce.class);
+    @Nonnull private final Logger log = LoggerFactory.getLogger(AddNonce.class);
     
     /** Strategy used to generate a nonce.*/
     @Nonnull private Function<ProfileRequestContext, Nonce> nonceGenerationStrategy;
     
     /** Constructor.*/
-    public PopulateNonce() {
+    public AddNonce() {
+        // Simple strategy that uses a secure random implementation to generate a nonce of length 16
         nonceGenerationStrategy = prc -> new Nonce(OIDCProxySupport.generateNonce(16));
     }
     
diff --git a/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/messaging/impl/AddRedirectURI.java b/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/AddRedirectURI.java
similarity index 65%
rename from idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/messaging/impl/AddRedirectURI.java
rename to idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/AddRedirectURI.java
index d8c7cca..84c35fb 100644
--- a/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/messaging/impl/AddRedirectURI.java
+++ b/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/AddRedirectURI.java
@@ -1,4 +1,21 @@
-package net.shibboleth.idp.plugin.authn.oidc.rp.messaging.impl;
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements.  See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You 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.authn.oidc.rp.impl;
 
 import java.net.URI;
 import java.util.function.BiFunction;
@@ -10,23 +27,23 @@ import javax.servlet.http.HttpServletRequest;
 
 import org.opensaml.messaging.context.MessageContext;
 import org.opensaml.messaging.context.navigate.RecursiveTypedParentContextLookup;
-import org.opensaml.messaging.handler.MessageHandlerException;
+import org.opensaml.profile.action.ActionSupport;
 import org.opensaml.profile.context.ProfileRequestContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.nimbusds.openid.connect.sdk.claims.ClaimsSet;
-
+import net.shibboleth.idp.authn.context.AuthenticationContext;
+import net.shibboleth.oidc.profile.core.OidcEventIds;
 import net.shibboleth.utilities.java.support.annotation.constraint.NonnullAfterInit;
 import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
 import net.shibboleth.utilities.java.support.component.ComponentSupport;
 import net.shibboleth.utilities.java.support.logic.Constraint;
 
-/** Adds a redirect_uri to the authentication request URL and the request object claims (if present).*/
-public class AddRedirectURI extends AbstractOIDCAuthenticationRequestMessageHandler {
-    
-    /** The name of the redirect uri claim.*/
-    private static final String REDIRECT_URI_CLAIM = "redirect_uri";
+/** 
+ * Adds a redirect_uri to the authentication request
+ * 
+ * TODO Events.*/
+public class AddRedirectURI extends AbstractOIDCAuthenticationRequestAction {
 
     /** Logger. */
     @Nonnull private final Logger log = LoggerFactory.getLogger(AddRedirectURI.class);
@@ -47,7 +64,7 @@ public class AddRedirectURI extends AbstractOIDCAuthenticationRequestMessageHand
      * 
      * @param strategy the strategy.
      */
-    public void setLocateProfileRequestContextStrategy(
+    public void setLocateProfileRequestContextStrategy(@Nonnull
             final Function<MessageContext, ProfileRequestContext> strategy) {
         ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
         ComponentSupport.ifDestroyedThrowDestroyedComponentException(this);
@@ -81,31 +98,20 @@ public class AddRedirectURI extends AbstractOIDCAuthenticationRequestMessageHand
         }
     }
 
-    /** {@inheritDoc} */
     @Override
-    protected void doInvoke(@Nonnull final MessageContext messageContext) throws MessageHandlerException {
-        
-        final ProfileRequestContext prc = locateProfileRequestContextStrategy.apply(messageContext);
-        if (prc == null) {
-            throw new MessageHandlerException(
-                    "Unable to locate the profile request context, redirect_uri can not be determined");
-        }
-        
+    protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext,
+            @Nonnull final AuthenticationContext authenticationContext) {     
+       
         final URI redirectUri = 
-                redirectUriCreationStrategy.apply(getOutboundMessageContext().getServletRequest(), prc);
+                redirectUriCreationStrategy.apply(getHttpServletRequest(), profileRequestContext);
         if (redirectUri == null) {
-            throw new MessageHandlerException("Redirect URI could not be located or created from strategy");
+            log.error("{} Redirect URI could not be located or created from strategy", getLogPrefix());
+            ActionSupport.buildEvent(profileRequestContext, OidcEventIds.INVALID_REDIRECT_URI);
+            return;
         }
         log.trace("Created redirect_uri '{}'", redirectUri);
         getAuthenticationRequest().setRedirectURI(redirectUri);
-        
-        // Also add to request object if exists
-        if (getAuthenticationRequest().getRequestObjectClaimsSet() != null) {            
-            final ClaimsSet claims = getAuthenticationRequest().getRequestObjectClaimsSet();
-            log.trace("{} Adding redirect_uri to JWT RequestObject", getLogPrefix());
-            claims.setClaim(REDIRECT_URI_CLAIM, redirectUri);           
-        } 
-         
+  
     }
 
 }
diff --git a/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/PopulateResponseTypeAndMode.java b/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/AddResponseTypeAndMode.java
similarity index 74%
rename from idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/PopulateResponseTypeAndMode.java
rename to idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/AddResponseTypeAndMode.java
index 232bcc6..c5e24db 100644
--- a/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/PopulateResponseTypeAndMode.java
+++ b/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/AddResponseTypeAndMode.java
@@ -17,12 +17,9 @@
 
 package net.shibboleth.idp.plugin.authn.oidc.rp.impl;
 
-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;
@@ -34,10 +31,7 @@ import com.nimbusds.oauth2.sdk.ResponseType;
 
 import net.shibboleth.idp.authn.context.AuthenticationContext;
 import net.shibboleth.idp.profile.IdPEventIds;
-import net.shibboleth.idp.profile.context.RelyingPartyContext;
 import net.shibboleth.oidc.profile.config.OIDCAuthorizationConfiguration;
-import net.shibboleth.utilities.java.support.component.ComponentSupport;
-import net.shibboleth.utilities.java.support.logic.Constraint;
 
 /**
  * Action that populates the authentication request response_mode and response_type from various stratagies, 
@@ -45,44 +39,15 @@ import net.shibboleth.utilities.java.support.logic.Constraint;
  * 
  *  TODO finish
  */
-public class PopulateResponseTypeAndMode extends AbstractOIDCAuthenticationRequestAction {
+public class AddResponseTypeAndMode extends AbstractOIDCAuthenticationRequestAction {
     
     /** The Default response type if none is selected.*/
     @Nonnull private static final ResponseType DEFAULT_RESPONSE_TYPE = ResponseType.CODE;
     
     /** Class logger. */
-    @Nonnull private final Logger log = LoggerFactory.getLogger(PopulateResponseTypeAndMode.class);
-    
-    /**
-     * Strategy used to locate the {@link RelyingPartyContext} associated with a given {@link ProfileRequestContext}.
-     */
-    @Nonnull private Function<ProfileRequestContext, RelyingPartyContext> relyingPartyContextLookupStrategy;
-
-    /** Applicable stashed profile configuration. */
-    @Nullable private OIDCAuthorizationConfiguration profileConfiguration;
+    @Nonnull private final Logger log = LoggerFactory.getLogger(AddResponseTypeAndMode.class);
     
     
-    /** Constructor.*/
-    public PopulateResponseTypeAndMode() {        
-        relyingPartyContextLookupStrategy = new ChildContextLookup<>(RelyingPartyContext.class);
-    }
-    
-    /**
-     * Set the strategy used to locate the {@link RelyingPartyContext} associated with a given
-     * {@link ProfileRequestContext}.
-     * 
-     * @param strategy lookup strategy
-     */
-    public void setRelyingPartyContextLookupStrategy(
-            @Nonnull final Function<ProfileRequestContext,RelyingPartyContext> strategy) {
-        ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
-        ComponentSupport.ifDestroyedThrowDestroyedComponentException(this);
-        
-        relyingPartyContextLookupStrategy =
-                Constraint.isNotNull(strategy, "RelyingPartyContext lookup strategy cannot be null");
-    }
-   
-    
     @Override
     protected boolean doPreExecute(@Nonnull final ProfileRequestContext profileRequestContext,
             @Nonnull final AuthenticationContext authenticationContext) {
@@ -97,19 +62,7 @@ public class PopulateResponseTypeAndMode extends AbstractOIDCAuthenticationReque
             ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_MSG_CTX);
             return false;
         }     
-        
-        final RelyingPartyContext rpCtx = relyingPartyContextLookupStrategy.apply(profileRequestContext);
-        if (rpCtx != null && rpCtx.getConfiguration() != null &&
-                rpCtx.getProfileConfig() instanceof OIDCAuthorizationConfiguration) {
-            profileConfiguration = (OIDCAuthorizationConfiguration) rpCtx.getProfileConfig();
-        }
-        if (profileConfiguration == null) {
-            log.error("{} Profile configuration not found", getLogPrefix());
-            ActionSupport.buildEvent(profileRequestContext, IdPEventIds.INVALID_PROFILE_CONFIG);
-            return false;
-        }
-        
-        
+
         return true;
     }
     
@@ -117,7 +70,7 @@ public class PopulateResponseTypeAndMode extends AbstractOIDCAuthenticationReque
     @Override protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext,
             @Nonnull final AuthenticationContext authenticationContext) {
         
-        final String responseTypeFromProfile = profileConfiguration.getResponseType(profileRequestContext); 
+        final String responseTypeFromProfile = getProfileConfiguration().getResponseType(profileRequestContext); 
         final ResponseType responseType = parseResponseType(responseTypeFromProfile);
         if (responseType == null){
             log.error("{} Response_type '{}' is not supported", getLogPrefix(), responseTypeFromProfile);
@@ -125,7 +78,7 @@ public class PopulateResponseTypeAndMode extends AbstractOIDCAuthenticationReque
             return;
         }
        
-        final String responseModeFromProfile = profileConfiguration.getResponseMode(profileRequestContext); 
+        final String responseModeFromProfile = getProfileConfiguration().getResponseMode(profileRequestContext); 
         final ResponseMode responseModeOverride = parseResponseMode(responseModeFromProfile);
                 
         final ResponseMode compatibleMode = ResponseMode.resolve(null, responseType);
diff --git a/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/PopulateScopes.java b/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/AddScopes.java
similarity index 95%
rename from idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/PopulateScopes.java
rename to idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/AddScopes.java
index 07d1d82..be6231a 100644
--- a/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/PopulateScopes.java
+++ b/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/AddScopes.java
@@ -30,10 +30,10 @@ import net.shibboleth.idp.authn.context.AuthenticationContext;
 /** 
  * An action that adds the scopes from the profile request object to the under constructions authentication request.
  */
-public class PopulateScopes extends AbstractOIDCAuthenticationRequestAction {
+public class AddScopes extends AbstractOIDCAuthenticationRequestAction {
     
     /** Class logger. */
-    @Nonnull private final Logger log = LoggerFactory.getLogger(PopulateScopes.class);
+    @Nonnull private final Logger log = LoggerFactory.getLogger(AddScopes.class);
     
     @Override
     protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext,
diff --git a/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/AuthorizationController.java b/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/AuthorizationController.java
index 37ac136..0fbdb2a 100644
--- a/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/AuthorizationController.java
+++ b/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/AuthorizationController.java
@@ -206,10 +206,9 @@ public class AuthorizationController extends AbstractInitializableComponent {
         if (nestedPRC.getOutboundMessageContext() != null &&
                 nestedPRC.getOutboundMessageContext().getMessage() instanceof OIDCAuthenticationRequest) {
             
-            // Build a handler context to allow certain parameters to be set e.g. state, redirect_uri, 
+            // Build a handler context to allow certain parameters to be set e.g. state, 
             // by the pre-message-encoders.
-            final OutboundMessageHandlerContext handlerContext = new OutboundMessageHandlerContext(httpRequest,
-                    httpResponse, key);
+            final OutboundMessageHandlerContext handlerContext = new OutboundMessageHandlerContext(key);
             
             nestedPRC.getOutboundMessageContext().addSubcontext(handlerContext);                    
             
diff --git a/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/BuildRequestObject.java b/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/BuildRequestObject.java
index 7402645..4aaa48b 100644
--- a/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/BuildRequestObject.java
+++ b/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/BuildRequestObject.java
@@ -56,12 +56,20 @@ public class BuildRequestObject extends AbstractOIDCAuthenticationRequestAction
     /** A hook to allow additional checking of the request object claims after it is build.*/
     @Nonnull private Predicate<ClaimsSet> claimsSetIsValidPredicate;
     
+    /** 
+     * Is the request object going to be signed? if so the 'iss' and 'aud' claims will be set.
+     * Defaults to always true, as it is permissible that both 'iss' and 'aud' claim can exist in 
+     * plain request objects.
+     */
+    @Nonnull private Predicate<ProfileRequestContext> requestObjectToBeSignedPredicate;
+    
     /** The RelyingPartyContext to operate on. */
     @Nullable private RelyingPartyContext rpCtx;
     
     /** Constructor.*/
     public BuildRequestObject() {
         claimsSetIsValidPredicate = Predicates.alwaysTrue();
+        requestObjectToBeSignedPredicate = Predicates.alwaysTrue();
     }
     
     /**
@@ -79,6 +87,21 @@ public class BuildRequestObject extends AbstractOIDCAuthenticationRequestAction
             claimsSetIsValidPredicate = predicate;
         }
     }
+    
+    /**
+     * Set a predicate to determine if the request object will be 'eventually' signed. If so,
+     * the 'iss' and 'aud' claims will be set into the request object.
+     * 
+     * @param predicate the predicate
+     */
+    public void setRequestObjectToBeSignedPredicate(@Nullable final Predicate<ProfileRequestContext> predicate) {
+        ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
+        ComponentSupport.ifDestroyedThrowDestroyedComponentException(this);
+        
+        if (predicate != null) {
+            requestObjectToBeSignedPredicate = predicate;
+        }
+    }
 
     /** {@inheritDoc} */
     @Override
@@ -88,28 +111,25 @@ public class BuildRequestObject extends AbstractOIDCAuthenticationRequestAction
         log.debug("{} Building a plain RequestObject JWT", getLogPrefix());
         final ClaimsSet requestObjectClaims = new ClaimsSet();     
         
-        //TODO check we are signing if we have selected a signing params, or if we just say must sign?
-        
-        requestObjectClaims.setClaim("client_id", getAuthenticationRequest().getClientID());
-        requestObjectClaims.setAudience(
-                new Audience(getProviderMetadataContext().getProviderInformation().getIssuer().getValue()));
-        requestObjectClaims.setIssuer(new Issuer(getAuthenticationRequest().getClientID().getValue())); 
+        if (requestObjectToBeSignedPredicate.test(profileRequestContext)) {
+            requestObjectClaims.setAudience(
+                    new Audience(getProviderMetadataContext().getProviderInformation().getIssuer().getValue()));
+            requestObjectClaims.setIssuer(new Issuer(getAuthenticationRequest().getClientID().getValue())); 
+        }
         
-        //FIXME: replace with static claim names?
-        requestObjectClaims.setClaim("nonce", getAuthenticationRequest().getNonce().getValue());
         
-        requestObjectClaims.setClaim("response_type", getAuthenticationRequest().getResponseType());
+        requestObjectClaims.setClaim("client_id", getAuthenticationRequest().getClientID().toString());    
+        requestObjectClaims.setClaim("nonce", getAuthenticationRequest().getNonce().getValue());        
+        requestObjectClaims.setClaim("response_type", getAuthenticationRequest().getResponseType().toString());
         // Only set the response_mode if not equal to the default for that response_type
         if (!getAuthenticationRequest().getDefaultResponseMode().equals(getAuthenticationRequest().getResponseMode())){
             requestObjectClaims.setClaim("response_mode", getAuthenticationRequest().getResponseMode());
         }
-        
-        requestObjectClaims.setClaim("scope", getAuthenticationRequest().getScope());
-        
-        // ACRs?
+        requestObjectClaims.setClaim("redirect_uri", getAuthenticationRequest().getRedirectURI().toString());
+        requestObjectClaims.setClaim("scope", getAuthenticationRequest().getScope().toString());
         
         // Validate the request object
-        if (!validateRequestObject(requestObjectClaims)) {
+        if (!validateRequestObject(profileRequestContext, requestObjectClaims)) {
             log.error("{} RequestObject claims are not valid", getLogPrefix());
             ActionSupport.buildEvent(profileRequestContext, AuthnEventIds.INVALID_AUTHN_CTX);
             return;
@@ -128,17 +148,19 @@ public class BuildRequestObject extends AbstractOIDCAuthenticationRequestAction
     /**
      * Ensure the request object is valid by assessing the claims are correct.
      * 
+     * @param profileRequestContext the profile request context
      * @param requestObjectClaims the claims of the request object
      * 
      * @return true if the request object claims are valid, false otherwise
      */
-    private boolean validateRequestObject(final ClaimsSet requestObjectClaims) {
+    private boolean validateRequestObject(@Nonnull final ProfileRequestContext profileRequestContext, 
+            @Nonnull final ClaimsSet requestObjectClaims) {
         
         if (!claimsSetIsValidPredicate.test(requestObjectClaims)) {
             return false;
         }
-        // TODO only if signing is enabled
-        if (true) {
+       
+        if (requestObjectToBeSignedPredicate.test(profileRequestContext)) {
             if (requestObjectClaims.getClaim("iss") == null) {
                 return false;
             }
diff --git a/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/PopulateJWTEncryptionParameters.java b/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/PopulateJWTEncryptionParameters.java
new file mode 100644
index 0000000..e8be51e
--- /dev/null
+++ b/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/PopulateJWTEncryptionParameters.java
@@ -0,0 +1,294 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements.  See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You 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.authn.oidc.rp.impl;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.function.Function;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.opensaml.messaging.context.navigate.ChildContextLookup;
+import org.opensaml.messaging.context.navigate.RecursiveTypedParentContextLookup;
+import org.opensaml.profile.action.ActionSupport;
+import org.opensaml.profile.action.EventIds;
+import org.opensaml.profile.context.ProfileRequestContext;
+import org.opensaml.saml.saml2.profile.context.EncryptionContext;
+import org.opensaml.xmlsec.EncryptionConfiguration;
+import org.opensaml.xmlsec.EncryptionParameters;
+import org.opensaml.xmlsec.EncryptionParametersResolver;
+import org.opensaml.xmlsec.SecurityConfigurationSupport;
+import org.opensaml.xmlsec.criterion.EncryptionConfigurationCriterion;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import net.shibboleth.idp.profile.AbstractProfileAction;
+import net.shibboleth.idp.profile.context.RelyingPartyContext;
+import net.shibboleth.oidc.metadata.context.OIDCMetadataContext;
+import net.shibboleth.oidc.metadata.context.OIDCProviderMetadataContext;
+import net.shibboleth.oidc.profile.config.OIDCAuthorizationConfiguration;
+import net.shibboleth.oidc.security.criterion.ClientInformationCriterion;
+import net.shibboleth.oidc.security.criterion.ProviderMetadataCriterion;
+import net.shibboleth.oidc.security.criterion.StaticCredentialCriterion;
+import net.shibboleth.utilities.java.support.annotation.constraint.NonnullAfterInit;
+import net.shibboleth.utilities.java.support.annotation.constraint.NonnullElements;
+import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
+import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
+import net.shibboleth.utilities.java.support.component.ComponentSupport;
+import net.shibboleth.utilities.java.support.logic.Constraint;
+import net.shibboleth.utilities.java.support.resolver.CriteriaSet;
+import net.shibboleth.utilities.java.support.resolver.ResolverException;
+
+
+//TODO similar to PopulateOIDCEncryptionParameters? shall we merge into commons, adds the OP metadata from downstream
+// If exists, useful for proxy.
+// TODO move to commons?
+public class PopulateJWTEncryptionParameters extends AbstractProfileAction {
+
+    /** Class logger. */
+    @Nonnull private final Logger log = LoggerFactory.getLogger(PopulateJWTEncryptionParameters.class);
+    
+    /** A friendly name to log as the subject of encryption parameter resolution.*/
+    @Nonnull private String forFriendlyName;
+    
+    /** Strategy used to look up the {@link EncryptionContext} to store parameters in. */
+    @Nonnull private final Function<ProfileRequestContext,EncryptionContext> encryptionContextLookupStrategy;
+
+    /** Strategy used to look up a per-request {@link EncryptionConfiguration} list. */
+    @NonnullAfterInit private Function<ProfileRequestContext,List<EncryptionConfiguration>> configurationLookupStrategy;
+    
+    /** Resolver for parameters to store into context. */
+    @NonnullAfterInit private EncryptionParametersResolver encParamsresolver;
+    
+    /** Active configurations to feed into resolver. */
+    @Nullable @NonnullElements private List<EncryptionConfiguration> encryptionConfigurations;
+    
+    /** Strategy used to look up a OIDC client metadata context. */
+    @Nullable private Function<ProfileRequestContext, OIDCMetadataContext> oidcClientMetadataContextLookupStrategy;
+    
+    /** Strategy used to look up a OIDC provider metadata context. */
+    @Nullable 
+    private Function<ProfileRequestContext, OIDCProviderMetadataContext> oidcProviderMetadataContextLookupStrategy;
+    
+    /** Lookup function for relying party context. */
+    @Nonnull private Function<ProfileRequestContext, RelyingPartyContext> relyingPartyContextLookupStrategy;
+    
+    /** Context to populate. */
+    private EncryptionContext encryptionContext;
+    
+    /** Constructor. */
+    public PopulateJWTEncryptionParameters() {
+        forFriendlyName = "not-specified";
+        encryptionContextLookupStrategy = new ChildContextLookup<>(EncryptionContext.class, true);
+        oidcClientMetadataContextLookupStrategy = new ChildContextLookup<>(OIDCMetadataContext.class);
+        oidcProviderMetadataContextLookupStrategy = new ChildContextLookup<>(OIDCProviderMetadataContext.class);
+        relyingPartyContextLookupStrategy =  new ChildContextLookup<>(RelyingPartyContext.class)
+                .compose(new RecursiveTypedParentContextLookup<>(ProfileRequestContext.class));
+    }
+    
+    /**
+     * Set lookup strategy for relying party context.
+     * 
+     * @param strategy  lookup strategy
+     */
+    public void setRelyingPartyContextLookupStrategy(
+            @Nonnull final Function<ProfileRequestContext, RelyingPartyContext> strategy) {
+        ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
+        
+        relyingPartyContextLookupStrategy =
+                Constraint.isNotNull(strategy, "RelyingPartyContext lookup strategy cannot be null");
+    }
+    
+    /**
+     * Set lookup strategy for {@link OIDCMetadataContext} for input to resolution.
+     * 
+     * @param strategy lookup strategy
+     */
+    public void setClientMetadataContextLookupStrategy(
+            @Nullable final Function<ProfileRequestContext, OIDCMetadataContext> strategy) {
+        ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
+
+        oidcClientMetadataContextLookupStrategy = strategy;
+    }
+    
+    /**
+     * Set lookup strategy for {@link OIDCProviderMetadataContext} for input to resolution.
+     * 
+     * @param strategy lookup strategy
+     */
+    public void setProviderMetadataContextLookupStrategy(
+            @Nullable final Function<ProfileRequestContext, OIDCProviderMetadataContext> strategy) {
+        ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
+
+        oidcProviderMetadataContextLookupStrategy = strategy;
+    }
+    
+    /**
+     * Set the friendly name to log as the subject of encryption parameter resolution.
+     * 
+     * @param name the friendly name
+     */
+    public void setForFriendlyName(@Nonnull @NotEmpty final String name) {
+        ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
+        ComponentSupport.ifDestroyedThrowDestroyedComponentException(this);
+
+        forFriendlyName = Constraint.isNotEmpty(name, "ForFriendlyName can not be null or empty");
+    }
+    
+    /**
+     * Set the strategy used to look up a per-request {@link EncryptionConfiguration} list.
+     * 
+     * @param strategy lookup strategy
+     */
+    public void setConfigurationLookupStrategy(
+            @Nonnull final Function<ProfileRequestContext, List<EncryptionConfiguration>> strategy) {
+        ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
+        ComponentSupport.ifDestroyedThrowDestroyedComponentException(this);
+
+        configurationLookupStrategy =
+                Constraint.isNotNull(strategy, "EncryptionConfiguration lookup strategy cannot be null");
+    }
+    
+    /**
+     * Set the encParamsresolver to use for the parameters to store into the context.
+     * 
+     * @param newResolver encParamsresolver to use
+     */
+    public void setEncryptionParametersResolver(@Nonnull final EncryptionParametersResolver newResolver) {
+        ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
+
+        encParamsresolver = Constraint.isNotNull(newResolver, "EncryptionParametersResolver cannot be null");
+    }
+    
+    @Override
+    protected void doInitialize() throws ComponentInitializationException {
+        super.doInitialize();
+
+        if (encParamsresolver == null) {
+            throw new ComponentInitializationException("EncryptionParametersResolver cannot be null");
+        } else if (configurationLookupStrategy == null) {
+            configurationLookupStrategy = new Function<ProfileRequestContext, List<EncryptionConfiguration>>() {
+                @Override
+                public List<EncryptionConfiguration> apply(final ProfileRequestContext input) {
+                    return Collections.singletonList(SecurityConfigurationSupport.getGlobalEncryptionConfiguration());
+                }
+            };
+        }
+    }
+    
+    @Override
+    protected boolean doPreExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
+        if (!super.doPreExecute(profileRequestContext)) {
+            log.debug("{} Encryption disabled", getLogPrefix());
+            return false;
+        }
+        
+        encryptionContext = encryptionContextLookupStrategy.apply(profileRequestContext);
+        if (encryptionContext == null) {
+            log.debug("{} No EncryptionContext returned by lookup strategy", getLogPrefix());
+            ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_PROFILE_CTX);
+            return false;
+        }        
+        return true;
+    }
+    
+    
+ // Checkstyle: CyclomaticComplexity OFF
+    @Override
+    protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext) {
+
+        log.debug("{} Resolving EncryptionParameters for {}", getLogPrefix(),forFriendlyName);
+        
+        try {
+            encryptionConfigurations = configurationLookupStrategy.apply(profileRequestContext);
+            if (encryptionConfigurations == null || encryptionConfigurations.isEmpty()) {
+                throw new ResolverException("No EncryptionConfigurations returned by lookup strategy");
+            }
+            final CriteriaSet criteria = buildCriteriaSet(profileRequestContext);
+            final EncryptionParameters params = encParamsresolver.resolveSingle(criteria);
+            
+            if (params != null) {
+                log.debug("{} Resolved EncryptionParameters for {}", getLogPrefix(),forFriendlyName);
+                encryptionContext.setAssertionEncryptionParameters(params);                
+            } else {               
+                log.warn("{} Resolver returned no EncryptionParameters", getLogPrefix());
+                ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_SEC_CFG);            
+            }
+        } catch (final ResolverException e) {
+            log.error("{} Error resolving EncryptionParameters", getLogPrefix(), e);            
+            ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_SEC_CFG);            
+        }
+    }
+// Checkstyle: CyclomaticComplexity ON
+    
+    /**
+     * Build the criteria used as input to the {@link EncryptionParametersResolver}.
+     * 
+     * @param profileRequestContext current profile request context
+     * 
+     * @return the criteria set to use
+     */
+    @Nonnull
+    private CriteriaSet buildCriteriaSet(@Nonnull final ProfileRequestContext profileRequestContext) {
+
+        final CriteriaSet criteria = new CriteriaSet(new EncryptionConfigurationCriterion(encryptionConfigurations));
+        
+     // Add client metadata criterion
+        final OIDCMetadataContext oidcMetadataCtx = 
+                oidcClientMetadataContextLookupStrategy.apply(profileRequestContext);
+        if (oidcMetadataCtx != null && oidcMetadataCtx.getClientInformation() != null) {
+            log.debug(
+                    "{} Adding OIDC client information to resolution criteria for encryption algorithms",
+                    getLogPrefix());
+            criteria.add(new ClientInformationCriterion(oidcMetadataCtx.getClientInformation()));
+        } else {
+            log.debug("{} No OIDC client information available", getLogPrefix());
+        }
+        
+        // Add OP metadata criterion
+        final OIDCProviderMetadataContext oidcProviderMetadataCtx = 
+                oidcProviderMetadataContextLookupStrategy.apply(profileRequestContext);
+        if (oidcProviderMetadataCtx != null && oidcProviderMetadataCtx.getProviderInformation() != null) {
+            log.debug("{} Adding OIDC provider information to resolution criteria for signing/digest algorithms",
+                    getLogPrefix());
+            criteria.add(new ProviderMetadataCriterion(oidcProviderMetadataCtx.getProviderInformation()));
+        } else {
+            log.debug("{} OIDCProviderMetadataContext is absent", getLogPrefix());
+        }
+        
+        // Add any static credentials from the RP context
+        final RelyingPartyContext rpCtx = 
+                relyingPartyContextLookupStrategy.apply(profileRequestContext);     
+        if (rpCtx != null && rpCtx.getConfiguration() != null &&
+                rpCtx.getProfileConfig() instanceof OIDCAuthorizationConfiguration) {
+            final OIDCAuthorizationConfiguration profileConfiguration = 
+                    (OIDCAuthorizationConfiguration) rpCtx.getProfileConfig();
+            
+            if (profileConfiguration != null) {
+                criteria.add(
+                        new StaticCredentialCriterion(profileConfiguration.getClientCredential(profileRequestContext)));
+            } else {
+                log.trace("{} Profile configuration not available, "
+                        + "shared secret direct encryption credential not present", getLogPrefix());
+            }
+        }
+        return criteria;
+    }
+
+}
diff --git a/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/RelyingPartyProxyEncryptionParametersResolver.java b/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/RelyingPartyProxyEncryptionParametersResolver.java
new file mode 100644
index 0000000..defc219
--- /dev/null
+++ b/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/RelyingPartyProxyEncryptionParametersResolver.java
@@ -0,0 +1,68 @@
+package net.shibboleth.idp.plugin.authn.oidc.rp.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.Predicate;
+
+import javax.annotation.Nonnull;
+
+import org.opensaml.security.credential.Credential;
+import org.opensaml.xmlsec.EncryptionParameters;
+import org.opensaml.xmlsec.impl.BasicEncryptionParametersResolver;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.nimbusds.jose.JWSAlgorithm;
+
+import net.shibboleth.oidc.security.criterion.StaticCredentialCriterion;
+import net.shibboleth.utilities.java.support.resolver.CriteriaSet;
+
+public class RelyingPartyProxyEncryptionParametersResolver extends BasicEncryptionParametersResolver {
+    
+    /** Logger. */
+    private final Logger log = LoggerFactory.getLogger(RelyingPartyProxyEncryptionParametersResolver.class);
+    
+    @Override
+    protected void resolveAndPopulateCredentialsAndAlgorithms(@Nonnull final EncryptionParameters params,
+            @Nonnull final CriteriaSet criteria, @Nonnull final Predicate<String> includeExcludePredicate) {
+        
+        super.resolveAndPopulateCredentialsAndAlgorithms(params, criteria, includeExcludePredicate);
+//        final List<Credential> allCredentials = new ArrayList<>();
+//        
+//        // Add any static credentials from the criteria
+//        if (criteria.contains(StaticCredentialCriterion.class)) {
+//            final Credential staticCred = criteria.get(StaticCredentialCriterion.class).getCredential();
+//            log.trace("Signing credential found in criterion '{}'", staticCred.getKeyNames());
+//            allCredentials.add(staticCred);
+//        }
+//        
+//        // Add any credentials from the configuration
+//        allCredentials.addAll(getEffectiveDataEncryptionCredentials(criteria));
+//        
+//        // Get effective signature algorithms from configuration and include/exclude predicate
+//        final List<String> algorithms = getEffectiveSignatureAlgorithms(criteria, includeExcludePredicate);        
+//        
+//        // Filter by those supported by the downstream OP
+//        final List<String> filteredAlgorithms = filterForOPSupportedAlgorithms(criteria, algorithms);
+//        final List<JWSAlgorithm> supportedAlgorithms = convertSupportAlgorithmsToJwkAlgorithms(filteredAlgorithms);
+//        log.trace("Resolved effective signature algorithms: {}", supportedAlgorithms);
+//        
+//        // Pick the first credential that matches one of the supported algorithms
+//        for (final Credential credential : allCredentials) {
+//            log.trace("Evaluating signing credential '{}'", credential.getKeyNames());
+//            final JWSAlgorithm foundSupportedAlgorithm = 
+//                    credentialSupportsSigningAlgorithm(credential, supportedAlgorithms);
+//            if (foundSupportedAlgorithm != null) {    
+//                log.trace("Credential supports algorithm '{}'", foundSupportedAlgorithm);
+//                params.setSigningCredential(credential);
+//                params.setSignatureAlgorithm(foundSupportedAlgorithm.getName());
+//                return;
+//            }
+//            log.trace("Credential failed eval against Signing Algorithm");
+//            
+//        }
+    }
+    
+    
+
+}
diff --git a/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/RelyingPartyProxySigningParametersResolver.java b/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/RelyingPartyProxySigningParametersResolver.java
index 7ab808b..9b2f191 100644
--- a/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/RelyingPartyProxySigningParametersResolver.java
+++ b/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/RelyingPartyProxySigningParametersResolver.java
@@ -114,7 +114,7 @@ public class RelyingPartyProxySigningParametersResolver extends BasicSignatureSi
         final List<String> algorithms = getEffectiveSignatureAlgorithms(criteria, includeExcludePredicate);        
         
         // Filter by those supported by the downstream OP
-        final List<String> filteredAlgorithms = filterForOPSupportedAlgorithms(criteria, algorithms);
+        final List<String> filteredAlgorithms = filterForProviderSupportedAlgorithms(criteria, algorithms);
         final List<JWSAlgorithm> supportedAlgorithms = convertSupportAlgorithmsToJwkAlgorithms(filteredAlgorithms);
         log.trace("Resolved effective signature algorithms: {}", supportedAlgorithms);
         
@@ -221,7 +221,7 @@ public class RelyingPartyProxySigningParametersResolver extends BasicSignatureSi
      * 
      * @return the current set of supported algorithms filtered by those also supported by the OP.
      */
-    private List<String> filterForOPSupportedAlgorithms(
+    private List<String> filterForProviderSupportedAlgorithms(
             @Nonnull final CriteriaSet criteria, @Nonnull final List<String> algorithms) {
 
         if (criteria.contains(ProviderMetadataCriterion.class)) {
@@ -231,14 +231,14 @@ public class RelyingPartyProxySigningParametersResolver extends BasicSignatureSi
             log.trace("Provider metadata supports the following signature algorithms '{}'",opSupportedAlgNames);
             
             if (opSupportedAlgNames == null) {
-                log.trace("Lookup strategy could not determine OP supported algorithms from metadata, "
+                log.trace("Lookup strategy could not determine provider supported algorithms from metadata, "
                         + "no further filtering performed");
                 return List.copyOf(algorithms);
             }
             return algorithms.stream().filter(opSupportedAlgNames::contains).collect(Collectors.toList());
             
         } else {
-            log.debug("No provider metadata criterion, unable to filter for OP supported algorithms");
+            log.debug("No provider metadata criterion, unable to filter for provider supported algorithms");
             return List.copyOf(algorithms);
         }
     }
diff --git a/idp-oidc-rp-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/authn/OIDCRelyingParty/oidc-relying-party-authn-beans.xml b/idp-oidc-rp-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/authn/OIDCRelyingParty/oidc-relying-party-authn-beans.xml
index a768faa..dcce53d 100644
--- a/idp-oidc-rp-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/authn/OIDCRelyingParty/oidc-relying-party-authn-beans.xml
+++ b/idp-oidc-rp-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/authn/OIDCRelyingParty/oidc-relying-party-authn-beans.xml
@@ -105,30 +105,38 @@
         class="net.shibboleth.idp.plugin.authn.oidc.rp.impl.InitializeAuthorizationRequest" scope="prototype"
         p:profileContextLookupStrategy-ref="shibboleth.ChildLookup.ProxyProfileRequestContext" />
 
-    <bean id="PopulateResponseTypeAndMode" scope="prototype"
-        class="net.shibboleth.idp.plugin.authn.oidc.rp.impl.PopulateResponseTypeAndMode"
+    <bean id="AddResponseTypeAndMode" scope="prototype"
+        class="net.shibboleth.idp.plugin.authn.oidc.rp.impl.AddResponseTypeAndMode"
         p:profileContextLookupStrategy-ref="shibboleth.ChildLookup.ProxyProfileRequestContext"
         p:authenticationContextLookupStrategy-ref="ParentAuthenticiationContextLookup" />
 
-    <bean id="PopulateScopes" scope="prototype" class="net.shibboleth.idp.plugin.authn.oidc.rp.impl.PopulateScopes"
+    <bean id="AddScopes" scope="prototype" class="net.shibboleth.idp.plugin.authn.oidc.rp.impl.AddScopes"
         p:profileContextLookupStrategy-ref="shibboleth.ChildLookup.ProxyProfileRequestContext"
         p:authenticationContextLookupStrategy-ref="ParentAuthenticiationContextLookup" />
 
-    <bean id="PopulateNonce" scope="prototype" class="net.shibboleth.idp.plugin.authn.oidc.rp.impl.PopulateNonce"
+    <bean id="AddNonce" scope="prototype" class="net.shibboleth.idp.plugin.authn.oidc.rp.impl.AddNonce"
         p:profileContextLookupStrategy-ref="shibboleth.ChildLookup.ProxyProfileRequestContext"
         p:authenticationContextLookupStrategy-ref="ParentAuthenticiationContextLookup" />
 
-    <bean id="PopulateEndpointURI" scope="prototype"
-        class="net.shibboleth.idp.plugin.authn.oidc.rp.impl.PopulateEndpointURI"
+    <bean id="AddEndpointURI" scope="prototype"
+        class="net.shibboleth.idp.plugin.authn.oidc.rp.impl.AddEndpointURI"
         p:profileContextLookupStrategy-ref="shibboleth.ChildLookup.ProxyProfileRequestContext"
-        p:authenticationContextLookupStrategy-ref="ParentAuthenticiationContextLookup" />
+        p:authenticationContextLookupStrategy-ref="ParentAuthenticiationContextLookup" />        
+        
+    <bean id="AddRedirectURI" scope="prototype"
+        class="net.shibboleth.idp.plugin.authn.oidc.rp.impl.AddRedirectURI"
+        p:profileContextLookupStrategy-ref="shibboleth.ChildLookup.ProxyProfileRequestContext"
+        p:authenticationContextLookupStrategy-ref="ParentAuthenticiationContextLookup" 
+        p:httpServletRequest-ref="shibboleth.HttpServletRequest"
+        p:redirectUriCreationStrategy="#{getObject('shibboleth.oidc.rp.RedirectUriCreationStrategy') ?: getObject('shibboleth.oidc.rp.DefaultRedirectUriCreationStrategy')}" />
 
-    <bean id="PopulateACRs" scope="prototype" class="net.shibboleth.idp.plugin.authn.oidc.rp.impl.PopulateACRs"
+    <bean id="AddAuthenticationContextClassReferences" scope="prototype" 
+        class="net.shibboleth.idp.plugin.authn.oidc.rp.impl.AddAuthenticationContextClassReferences"
         p:profileContextLookupStrategy-ref="shibboleth.ChildLookup.ProxyProfileRequestContext"
         p:authenticationContextLookupStrategy-ref="ParentAuthenticiationContextLookup" />
 
-    <bean id="PopulateForceAuthenticationPrompt" scope="prototype"
-        class="net.shibboleth.idp.plugin.authn.oidc.rp.impl.PopulateForceAuthenticationPrompt"
+    <bean id="AddForceAuthenticationPrompt" scope="prototype"
+        class="net.shibboleth.idp.plugin.authn.oidc.rp.impl.AddForceAuthenticationPrompt"
         p:profileContextLookupStrategy-ref="shibboleth.ChildLookup.ProxyProfileRequestContext"
         p:authenticationContextLookupStrategy-ref="ParentAuthenticiationContextLookup" />
 
@@ -137,33 +145,58 @@
         class="net.shibboleth.idp.plugin.authn.oidc.rp.messaging.context.logic.RequestObjectRequiredAndSupported" />
 
 
+
+    <bean id="shibboleth.authn.oidc.rp.DefaultSignRequestObjectCondition" 
+                class="net.shibboleth.idp.plugin.authn.oidc.rp.config.logic.SignRequestObjectPredicate"
+                p:relyingPartyContextLookupStrategy-ref="shibboleth.ChildLookup.Proxy.RelyingPartyContext"/>
+                
+    <bean id="shibboleth.authn.oidc.rp.DefaultEncryptRequestObjectCondition" 
+                class="net.shibboleth.idp.plugin.authn.oidc.rp.config.logic.EncryptRequestObjectPredicate"
+                p:relyingPartyContextLookupStrategy-ref="shibboleth.ChildLookup.RelyingParty"/>
+                
     <bean id="PopulateRequestObjectSignatureSigningParameters"
         class="net.shibboleth.oidc.security.impl.PopulateJWTSignatureSigningParameters"
         c:strategy-ref="shibboleth.ChildLookup.Proxy.MessageContextLookup.Inbound"
+        p:noResultIsError="true"
         p:configurationLookupStrategy-ref="RequestObjectSignatureSigningConfigurationLookup"
         p:providerMetadataContextLookupStrategy-ref="shibboleth.ChildLookup.OIDCProviderMetadataContextFromOutbound"
-        p:signatureSigningParametersResolver-ref="shibboleth.authn.oidc.rp.RequestObjectSignatureSigningParametersResolver">
-        <property name="activationCondition">
-            <bean class="net.shibboleth.idp.plugin.authn.oidc.rp.config.logic.SignRequestObjectPredicate"
-                p:relyingPartyContextLookupStrategy-ref="shibboleth.ChildLookup.Proxy.RelyingPartyContext"/>
-        </property>
-    </bean>
+        p:signatureSigningParametersResolver-ref="shibboleth.authn.oidc.rp.RequestObjectSignatureSigningParametersResolver"
+        p:activationCondition="#{getObject('shibboleth.authn.oidc.rp.SignRequestObjectCondition') ?: getObject('shibboleth.authn.oidc.rp.DefaultSignRequestObjectCondition')}"/>
 
     <bean id="shibboleth.authn.oidc.rp.RequestObjectSignatureSigningParametersResolver"
         class="net.shibboleth.idp.plugin.authn.oidc.rp.impl.RelyingPartyProxySigningParametersResolver"
         p:providerMetadataAlgorithmLookupStrategy-ref="shibboleth.authn.oidc.rp.RequestObjectSupportedSignatureSigningAlgorithms" />
 
-    <bean id="shibboleth.authn.oidc.rp.RequestObjectSupportedSignatureSigningAlgorithms"
+    <bean id="shibboleth.authn.oidc.rp.RequestObjectSupportedSignatureSigningAlgorithms" scope="prototype"
         class="net.shibboleth.idp.plugin.authn.oidc.rp.config.RequestObjectSupportedSignatureSigningAlgorithms" />
 
     <bean id="RequestObjectSignatureSigningConfigurationLookup" lazy-init="true"
         class="net.shibboleth.idp.plugin.authn.oidc.rp.config.navigate.RequestObjectSignatureSigningConfigurationLookupFunction"
         p:relyingPartyConfigurationResolver-ref="shibboleth.RelyingPartyConfigurationResolver" />
 
+    
+    <bean id="PopulateRequestObjectEncryptionParameters"
+        class="net.shibboleth.idp.plugin.authn.oidc.rp.impl.PopulateJWTEncryptionParameters" scope="prototype"
+        p:forFriendlyName="Request Object"
+        p:configurationLookupStrategy-ref="RequestObjectEncryptionConfigurationLookup"
+        p:profileContextLookupStrategy-ref="shibboleth.ChildLookup.ProxyProfileRequestContext"
+        p:providerMetadataContextLookupStrategy-ref="shibboleth.ChildLookup.OIDCProviderMetadataContextFromOutbound"
+        p:encryptionParametersResolver-ref="shibboleth.authn.oidc.rp.EncryptionParametersResolver" 
+        p:activationCondition="#{getObject('shibboleth.authn.oidc.rp.EncryptRequestObjectCondition') ?: getObject('shibboleth.authn.oidc.rp.DefaultEncryptRequestObjectCondition')}"/>
+        
+    <bean id="RequestObjectEncryptionConfigurationLookup" lazy-init="true"
+        class="net.shibboleth.idp.plugin.authn.oidc.rp.config.navigate.RequestObjectEncryptionConfigurationLookupFunction"
+        p:relyingPartyConfigurationResolver-ref="shibboleth.RelyingPartyConfigurationResolver" />
+
+    <bean id="shibboleth.authn.oidc.rp.EncryptionParametersResolver"
+        class="org.opensaml.xmlsec.impl.BasicEncryptionParametersResolver"/>
+    
+    
     <bean id="BuildRequestObject" class="net.shibboleth.idp.plugin.authn.oidc.rp.impl.BuildRequestObject"
         scope="prototype" p:profileContextLookupStrategy-ref="shibboleth.ChildLookup.ProxyProfileRequestContext"
         p:authenticationContextLookupStrategy-ref="ParentAuthenticiationContextLookup"
-        p:claimsSetIsValidPredicate="#{getObject('shibboleth.authn.oidc.rp.RequestObjectClaimsSetIsValidPredicate')}" />
+        p:claimsSetIsValidPredicate="#{getObject('shibboleth.authn.oidc.rp.RequestObjectClaimsSetIsValidPredicate')}" 
+        p:requestObjectToBeSignedPredicate="#{getObject('shibboleth.authn.oidc.rp.SignRequestObjectCondition') ?: getObject('shibboleth.authn.oidc.rp.DefaultSignRequestObjectCondition')}"/>
 
 
     <!-- Message Encoder factory is a prototype to allow reuse of the encoders -->
@@ -199,10 +232,6 @@
                     scope="prototype"
                     p:stateGenerationStrategy="#{getObject('shibboleth.authn.oidc.rp.StateGenerationStrategy')}" />
 
-                <bean id="AddRedirectURI"
-                    class="net.shibboleth.idp.plugin.authn.oidc.rp.messaging.impl.AddRedirectURI" scope="prototype"
-                    p:redirectUriCreationStrategy="#{getObject('shibboleth.oidc.rp.RedirectUriCreationStrategy') ?: getObject('shibboleth.oidc.rp.DefaultRedirectUriCreationStrategy')}" />
-
                 <bean id="BuildPlainRequestObjectJWT"
                     class="net.shibboleth.idp.plugin.authn.oidc.rp.messaging.impl.BuildPlainRequestObjectJWT"
                     scope="prototype" />
@@ -467,6 +496,18 @@
     <bean id="OIDCProviderMetadataContextChildLookup"
         class="org.opensaml.messaging.context.navigate.ChildContextLookup"
         c:type="#{ T(net.shibboleth.oidc.metadata.context.OIDCProviderMetadataContext) }" />
+        
+    <bean id="IDTokenRequiredClaimsValidator"
+        class="net.shibboleth.oidc.security.jwt.claims.impl.RequiredClaimsValidator"
+        p:requiredClaims-ref="IDTokenRequiredOIDCClaims"/>
+    
+    <util:set id="IDTokenRequiredOIDCClaims">
+        <value>iss</value>
+        <value>sub</value>
+        <value>aud</value>
+        <value>exp</value>
+        <value>iat</value>
+    </util:set>
 
     <bean id="ExpiryClaimsValidator" class="net.shibboleth.oidc.security.jwt.claims.impl.ExpiryClaimsValidator"
         p:clockSkew="%{idp.policy.clockSkew:PT1M}" />
@@ -548,6 +589,7 @@
         c:type="#{ T(net.shibboleth.idp.plugin.authn.oidc.rp.context.OIDCPeerEntityContext) }" />
 
     <util:list id="IDTokenClaimsValidators" value-type="net.shibboleth.oidc.jwt.claims.ClaimsValidator">
+        <ref bean="IDTokenRequiredClaimsValidator"/>
         <ref bean="IssuerClaimsValidator" /> <!-- TODO prevent: if it contains additional audiences not trusted by the Client. -->
         <ref bean="AudienceClaimsValidator" />
         <ref bean="AzpClaimRequiredValidator" />
@@ -680,15 +722,8 @@
 
     <bean id="DefaultUserInfoTokenLookupStrategy"
         class="net.shibboleth.idp.plugin.authn.oidc.rp.impl.DefaultUserInfoTokenLookupStrategy" />
-
-    <util:list id="UserInfoClaimsValidators" value-type="net.shibboleth.oidc.jwt.claims.ClaimsValidator">
-        <ref bean="SubClaimRequiredValidator" />
-        <ref bean="SubMatchesIDTokenClaimValidator" />
-        <ref bean="IssuerClaimsValidator" />
-        <ref bean="AudienceClaimsValidator" />
-    </util:list>
-
-    <bean id="SubClaimRequiredValidator"
+        
+    <bean id="UserInfoTokenRequiredClaimsValidator"
         class="net.shibboleth.oidc.security.jwt.claims.impl.RequiredClaimsValidator">
         <property name="requiredClaims">
             <list>
@@ -696,14 +731,23 @@
             </list>
         </property>
     </bean>
-
-    <bean id="SubMatchesIDTokenClaimValidator"
+    
+      <bean id="SubMatchesIDTokenClaimValidator"
         class="net.shibboleth.oidc.security.jwt.claims.impl.ExactMatchClaimsValidator" p:claimName="sub">
         <property name="valueToMatchLookupStrategy">
             <bean class="net.shibboleth.idp.plugin.authn.oidc.rp.config.navigate.SubFromIDTokenLookupFunction" />
         </property>
     </bean>
 
+    <util:list id="UserInfoClaimsValidators" value-type="net.shibboleth.oidc.jwt.claims.ClaimsValidator">
+        <ref bean="UserInfoTokenRequiredClaimsValidator" />
+        <ref bean="SubMatchesIDTokenClaimValidator" />
+        <ref bean="IssuerClaimsValidator" />
+        <ref bean="AudienceClaimsValidator" />
+    </util:list>
+
+  
+
 
 
     <!-- UserInfo Decryption and Signature Validation Done -->
@@ -736,22 +780,4 @@
         p:transcoderRegistry-ref="shibboleth.AttributeRegistryService" />
 
 
-
-
-    <!-- OLD STUFF -->
-
-
-    <bean id="shibboleth.authn.oidc.rp.jwt.DefaultAuthTimeActivationCondition"
-        class="net.shibboleth.oidc.security.jwt.claims.impl.ForcedAuthenticationActivationCondition" />
-
-
-    <!-- These represent the default set of id_token claims which are **required** by OIDC https://openid.net/specs/openid-connect-core-1_0.html#IDToken -->
-    <util:set id="shibboleth.authn.oidc.rp.DefaultRequiredOIDCClaims">
-        <value>iss</value>
-        <value>sub</value>
-        <value>aud</value>
-        <value>exp</value>
-        <value>iat</value>
-    </util:set>
-
 </beans>
diff --git a/idp-oidc-rp-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/authn/OIDCRelyingParty/oidc-relying-party-authn-flow.xml b/idp-oidc-rp-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/authn/OIDCRelyingParty/oidc-relying-party-authn-flow.xml
index 59ccafb..99eb402 100644
--- a/idp-oidc-rp-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/authn/OIDCRelyingParty/oidc-relying-party-authn-flow.xml
+++ b/idp-oidc-rp-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/authn/OIDCRelyingParty/oidc-relying-party-authn-flow.xml
@@ -34,12 +34,13 @@
         <evaluate expression="SelectProfileConfiguration" />
         <evaluate expression="InitializeOAuth2ClientContext" />
         <evaluate expression="InitializeAuthorizationRequest" />
-        <evaluate expression="PopulateResponseTypeAndMode" />
-        <evaluate expression="PopulateScopes" />
-        <evaluate expression="PopulateNonce" />
-        <evaluate expression="PopulateForceAuthenticationPrompt" />
-        <evaluate expression="PopulateEndpointURI" />
-        <evaluate expression="PopulateACRs" />
+        <evaluate expression="AddResponseTypeAndMode" />
+        <evaluate expression="AddScopes" />
+        <evaluate expression="AddNonce" />
+        <evaluate expression="AddForceAuthenticationPrompt" />
+        <evaluate expression="AddEndpointURI" />
+        <evaluate expression="AddRedirectURI"/>
+        <evaluate expression="AddAuthenticationContextClassReferences" />
         <!-- <evaluate expression="PostRequestPopulateAuditContext" /> <evaluate expression="WriteAuditLog" /> -->
 
         <!-- <evaluate expression="InitializeMessageChannelSecurityContext" /> -->
@@ -57,10 +58,11 @@
 
     <action-state id="BuildRequestObject">
         <evaluate expression="PopulateRequestObjectSignatureSigningParameters" />
+        <evaluate expression="PopulateRequestObjectEncryptionParameters" />
         <evaluate expression="BuildRequestObject" />
         <!-- We can not sign and encrypt the RO here, it has to be done as part of the controller so we can add state etc. -->
         <evaluate expression="'proceed'" />
-        <transition on="proceed" to="AuthRequest" />
+        <transition on="proceed" to="AuthnRequest" />
     </action-state>
 
     <view-state id="AuthnRequest"
diff --git a/idp-oidc-rp-impl/src/main/resources/META-INF/net/shibboleth/idp/service/relying-party/postconfig.xml b/idp-oidc-rp-impl/src/main/resources/META-INF/net/shibboleth/idp/service/relying-party/postconfig.xml
index 19bfa73..fbad510 100644
--- a/idp-oidc-rp-impl/src/main/resources/META-INF/net/shibboleth/idp/service/relying-party/postconfig.xml
+++ b/idp-oidc-rp-impl/src/main/resources/META-INF/net/shibboleth/idp/service/relying-party/postconfig.xml
@@ -35,6 +35,7 @@
         p:clientCredential="#{%{idp.authn.oidc.rp.discoveryRequired:false} == true ? {null} : getObject('shibboleth.authn.oidc.rp.DefaultCredential')}"
         p:tokenEndpointAuthMethods="%{idp.authn.oidc.rp.clientAuthenticationMethod:client_secret_basic}"
         p:responseMode="%{idp.authn.oidc.rp.responseMode:#{null}}"
+        p:redirectUriOverride="%{idp.authn.oidc.rp.client.redirectURL:#{null}}"
         p:scopes="%{idp.authn.oidc.rp.scopes:#{null}}">
         <property name="forceAuthnPredicate">
             <bean class="net.shibboleth.idp.saml.profile.config.logic.ProxyAwareForceAuthnPredicate" />
@@ -67,24 +68,70 @@
         class="net.shibboleth.oidc.profile.config.OIDCSecurityConfiguration">
         <property name="idTokenJwtDecryptionConfiguration">
             <ref
-                bean="#{'%{dp.authn.oidc.rp.idtoken.decrypt.config:shibboleth.authn.oidc.rp.DefaultJWTDecryptionConfiguration}'.trim()}" />
+                bean="#{'%{idp.authn.oidc.rp.idtoken.decrypt.config:shibboleth.authn.oidc.rp.DefaultJWTDecryptionConfiguration}'.trim()}" />
         </property>
         <property name="idTokenJwtSignatureValidationConfiguration">
             <ref
-                bean="#{'%{dp.authn.oidc.rp.idtoken.valid.config:shibboleth.authn.oidc.rp.DefaultJWTSignatureValidationConfiguration}'.trim()}" />
+                bean="#{'%{idp.authn.oidc.rp.idtoken.valid.config:shibboleth.authn.oidc.rp.DefaultJWTSignatureValidationConfiguration}'.trim()}" />
         </property>
         <!-- User info config is actually the same by default as id_token, not sure we need seperation, although could be overriden -->
         <property name="userInfoJwtDecryptionConfiguration">
             <ref
-                bean="#{'%{dp.authn.oidc.rp.userinfotoken.decrypt.config:shibboleth.authn.oidc.rp.DefaultJWTDecryptionConfiguration}'.trim()}" />
+                bean="#{'%{idp.authn.oidc.rp.userinfotoken.decrypt.config:shibboleth.authn.oidc.rp.DefaultJWTDecryptionConfiguration}'.trim()}" />
         </property>
         <property name="userInfoTokenJwtSignatureValidationConfiguration">
             <ref
-                bean="#{'%{dp.authn.oidc.rp.userinfotoken.valid.config:shibboleth.authn.oidc.rp.DefaultJWTSignatureValidationConfiguration}'.trim()}" />
+                bean="#{'%{idp.authn.oidc.rp.userinfotoken.valid.config:shibboleth.authn.oidc.rp.DefaultJWTSignatureValidationConfiguration}'.trim()}" />
         </property>
         <property name="requestObjectSignatureSigningConfiguration">
             <ref
-                bean="#{'%{dp.authn.oidc.rp.requestobject.signing.config:shibboleth.authn.oidc.rp.DefaultRequestObjectSigningConfiguration}'.trim()}" />
+                bean="#{'%{idp.authn.oidc.rp.requestobject.signing.config:shibboleth.authn.oidc.rp.DefaultRequestObjectSigningConfiguration}'.trim()}" />
+        </property>
+        <!-- For now, Request Object encryption configuration only -->
+        <property name="encryptionConfiguration">
+            <ref bean="#{'%{idp.authn.oidc.rp.encryption.config:shibboleth.authn.oidc.rp.EncryptionConfiguration}'.trim()}" />
+        </property>
+    </bean>
+    
+    <!-- Configuration for supported algorithms for Request Object encryption. -->
+    <bean id="shibboleth.authn.oidc.rp.EncryptionConfiguration" parent="shibboleth.BasicEncryptionConfiguration">
+        <property name="keyTransportEncryptionAlgorithms">
+            <list>
+                <util:constant
+                    static-field="net.shibboleth.oidc.jwa.support.KeyManagementConstants.ALGO_ID_ALG_RSA_1_5" />
+                <util:constant
+                    static-field="net.shibboleth.oidc.jwa.support.KeyManagementConstants.ALGO_ID_ALG_RSA_OAEP" />
+                <util:constant
+                    static-field="net.shibboleth.oidc.jwa.support.KeyManagementConstants.ALGO_ID_ALG_RSA_OAEP_256" />
+                <util:constant
+                    static-field="net.shibboleth.oidc.jwa.support.KeyManagementConstants.ALGO_ID_ALG_AES_128_KW" />
+                <util:constant
+                    static-field="net.shibboleth.oidc.jwa.support.KeyManagementConstants.ALGO_ID_ALG_AES_192_KW" />
+                <util:constant
+                    static-field="net.shibboleth.oidc.jwa.support.KeyManagementConstants.ALGO_ID_ALG_AES_256_KW" />
+                <util:constant
+                    static-field="net.shibboleth.oidc.jwa.support.KeyManagementConstants.ALGO_ID_ALG_AES_128_GCM_KW" />
+                <util:constant
+                    static-field="net.shibboleth.oidc.jwa.support.KeyManagementConstants.ALGO_ID_ALG_AES_192_GCM_KW" />
+                <util:constant
+                    static-field="net.shibboleth.oidc.jwa.support.KeyManagementConstants.ALGO_ID_ALG_AES_256_GCM_KW" />
+            </list>
+        </property>
+        <property name="dataEncryptionAlgorithms">
+            <list>
+                <util:constant
+                    static-field="net.shibboleth.oidc.jwa.support.EncryptionConstants.ALGO_ID_ENC_ALG_A128CBC_HS256" />
+                <util:constant
+                    static-field="net.shibboleth.oidc.jwa.support.EncryptionConstants.ALGO_ID_ENC_ALG_A192CBC_HS384" />
+                <util:constant
+                    static-field="net.shibboleth.oidc.jwa.support.EncryptionConstants.ALGO_ID_ENC_ALG_A256CBC_HS512" />
+                <util:constant
+                    static-field="net.shibboleth.oidc.jwa.support.EncryptionConstants.ALGO_ID_ENC_ALG_A128GCM" />
+                <util:constant
+                    static-field="net.shibboleth.oidc.jwa.support.EncryptionConstants.ALGO_ID_ENC_ALG_A192GCM" />
+                <util:constant
+                    static-field="net.shibboleth.oidc.jwa.support.EncryptionConstants.ALGO_ID_ENC_ALG_A256GCM" />
+            </list>
         </property>
     </bean>
     
diff --git a/idp-oidc-rp-impl/src/main/resources/net/shibboleth/idp/plugin/authn/oidc/rp/conf/authn/oidc-rp.properties b/idp-oidc-rp-impl/src/main/resources/net/shibboleth/idp/plugin/authn/oidc/rp/conf/authn/oidc-rp.properties
index 993518c..3ac15e4 100644
--- a/idp-oidc-rp-impl/src/main/resources/net/shibboleth/idp/plugin/authn/oidc/rp/conf/authn/oidc-rp.properties
+++ b/idp-oidc-rp-impl/src/main/resources/net/shibboleth/idp/plugin/authn/oidc/rp/conf/authn/oidc-rp.properties
@@ -2,6 +2,8 @@
 idp.authn.oidc.rp.proxyIssuer= <issuerId>
 
 
+idp.authn.oidc.rp.client.redirectURL= https://localhost/callback
+
 # If a redirect_uri is not explicitly declared above, one can be inferred from each
 # request's Host header. To avoid Host header injection attacks, the allowed origins
 # must be specified here. Origins are comma seperated. Do not specify the port when
@@ -9,6 +11,7 @@ idp.authn.oidc.rp.proxyIssuer= <issuerId>
 idp.authn.oidc.rp.client.redirecturl.allowedOrigins = https://localhost
 
 
+
 ## openid is defaulted. Other scopes could be; profile etc.
 #idp.oidc.rp.scope=openid
 
diff --git a/idp-oidc-rp-impl/src/test/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/PopulateResponseTypeAndModeTest.java b/idp-oidc-rp-impl/src/test/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/AddResponseTypeAndModeTest.java
similarity index 96%
rename from idp-oidc-rp-impl/src/test/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/PopulateResponseTypeAndModeTest.java
rename to idp-oidc-rp-impl/src/test/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/AddResponseTypeAndModeTest.java
index 5e226f3..e22887a 100644
--- a/idp-oidc-rp-impl/src/test/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/PopulateResponseTypeAndModeTest.java
+++ b/idp-oidc-rp-impl/src/test/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/AddResponseTypeAndModeTest.java
@@ -23,9 +23,9 @@ import net.shibboleth.oidc.profile.core.OIDCAuthenticationRequest;
 import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
 
 /** Tests for the PopulateResponseTypeAndMode action.*/
-public class PopulateResponseTypeAndModeTest extends AbstractOIDCTest {
+public class AddResponseTypeAndModeTest extends AbstractOIDCTest {
     
-    private PopulateResponseTypeAndMode action;
+    private AddResponseTypeAndMode action;
     
     private RelyingPartyContext rpc;
     
@@ -36,7 +36,7 @@ public class PopulateResponseTypeAndModeTest extends AbstractOIDCTest {
     @BeforeMethod
     public void setup() throws Exception {
         super.setup();
-        action = new PopulateResponseTypeAndMode(); 
+        action = new AddResponseTypeAndMode(); 
         rpc = prc.getSubcontext(RelyingPartyContext.class, true); 
         oidcAuthzConfig = new OIDCAuthorizationConfiguration();
         final RelyingPartyConfiguration rpConfig = new RelyingPartyConfiguration();
diff --git a/idp-oidc-rp-impl/src/test/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/AuthorizationControllerTest.java b/idp-oidc-rp-impl/src/test/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/AuthorizationControllerTest.java
index 98b636e..6d48544 100644
--- a/idp-oidc-rp-impl/src/test/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/AuthorizationControllerTest.java
+++ b/idp-oidc-rp-impl/src/test/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/AuthorizationControllerTest.java
@@ -29,7 +29,6 @@ import java.io.IOException;
 import java.net.URI;
 import java.net.URLEncoder;
 import java.util.ArrayList;
-import java.util.Set;
 
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
@@ -85,7 +84,6 @@ import net.shibboleth.idp.authn.impl.ExternalAuthenticationImpl;
 import net.shibboleth.idp.plugin.authn.oidc.rp.context.OAuth2ClientContext;
 import net.shibboleth.idp.plugin.authn.oidc.rp.context.OIDCAuthnContext;
 import net.shibboleth.idp.plugin.authn.oidc.rp.context.OIDCPeerEntityContext;
-import net.shibboleth.idp.plugin.authn.oidc.rp.messaging.impl.AddRedirectURI;
 import net.shibboleth.idp.plugin.authn.oidc.rp.messaging.impl.AddState;
 import net.shibboleth.idp.plugin.authn.oidc.rp.messaging.impl.BuildPlainRequestObjectJWT;
 import net.shibboleth.idp.plugin.authn.oidc.rp.messaging.impl.SignRequestObject;
@@ -277,10 +275,6 @@ public class AuthorizationControllerTest extends AbstractTestNGSpringContextTest
         
         final var addState = new AddState();
         addState.initialize();
-        final var addRedirectUri = new AddRedirectURI();
-        addRedirectUri.setRedirectUriCreationStrategy(
-                new DefaultRedirectUriCreationFunction("/Authn/OIDC/RP/callback", Set.of("http://localhost")));
-        addRedirectUri.initialize();
         final var signer = new SignRequestObject();
         signer.initialize();
         final var buildRequestObjectJwt = new BuildPlainRequestObjectJWT();
@@ -288,7 +282,6 @@ public class AuthorizationControllerTest extends AbstractTestNGSpringContextTest
         
         
         handlers.add(addState);
-        handlers.add(addRedirectUri);
         handlers.add(buildRequestObjectJwt);
         handlers.add(signer);
         chainingMsgHandler.setHandlers(handlers);        
@@ -312,9 +305,9 @@ public class AuthorizationControllerTest extends AbstractTestNGSpringContextTest
     }
     
     /**
-     * Build a nested {@link ProfileRequestContext} by configuring a suitable context tree for external authentication e.g. a
-     * {@link AuthenticationContext} and {@link ExternalAuthenticationContext}. Nest the proxy PRC under the authentication
-     * context.
+     * Build a nested {@link ProfileRequestContext} by configuring a suitable context tree for 
+     * external authentication e.g. a {@link AuthenticationContext} and {@link ExternalAuthenticationContext}.
+     * Nest the proxy PRC under the authentication context.
      * 
      * @return a profile request context.
      * @throws Exception on error creating the duo client
@@ -454,7 +447,8 @@ public class AuthorizationControllerTest extends AbstractTestNGSpringContextTest
             try {
                 
                 final MessageContext messageContext = getMessageContext();
-                final OIDCAuthenticationRequest outboundMessage = (OIDCAuthenticationRequest)messageContext.getMessage();
+                final OIDCAuthenticationRequest outboundMessage = 
+                        (OIDCAuthenticationRequest)messageContext.getMessage();
                 
     
                 final URLBuilder urlBuilder = new URLBuilder(outboundMessage.getEndpointURI().toString());
diff --git a/idp-oidc-rp-impl/src/test/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/OIDCRPFlowTest.java b/idp-oidc-rp-impl/src/test/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/OIDCRPFlowTest.java
index 2d3f7bc..986e995 100644
--- a/idp-oidc-rp-impl/src/test/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/OIDCRPFlowTest.java
+++ b/idp-oidc-rp-impl/src/test/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/OIDCRPFlowTest.java
@@ -21,7 +21,6 @@ import java.net.InetAddress;
 import java.net.URI;
 import java.net.UnknownHostException;
 import java.security.Principal;
-import java.time.Duration;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -29,7 +28,6 @@ import java.util.Set;
 
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
-import javax.crypto.spec.SecretKeySpec;
 
 import org.apache.http.conn.ssl.NoopHostnameVerifier;
 import org.apache.http.conn.ssl.TrustAllStrategy;
@@ -41,7 +39,6 @@ import org.opensaml.messaging.context.MessageContext;
 import org.opensaml.profile.context.ProfileRequestContext;
 import org.opensaml.security.credential.Credential;
 import org.opensaml.security.credential.CredentialResolver;
-import org.opensaml.security.credential.UsageType;
 import org.opensaml.xmlsec.config.GlobalAlgorithmRegistryInitializer;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -53,7 +50,6 @@ import org.springframework.webflow.engine.impl.FlowExecutionImpl;
 import org.springframework.webflow.execution.FlowExecution;
 import org.springframework.webflow.test.MockFlowBuilderContext;
 
-import com.nimbusds.jose.EncryptionMethod;
 import com.nimbusds.jose.JOSEException;
 import com.nimbusds.jose.JWEAlgorithm;
 import com.nimbusds.jose.jwk.RSAKey;
@@ -86,16 +82,12 @@ import net.shibboleth.oidc.metadata.context.OIDCProviderMetadataContext;
 import net.shibboleth.oidc.profile.config.OIDCAuthorizationConfiguration;
 import net.shibboleth.oidc.profile.config.OIDCSecurityConfiguration;
 import net.shibboleth.oidc.profile.core.OIDCAuthenticationRequest;
-import net.shibboleth.oidc.security.credential.BasicExpiringJWKCredential;
 import net.shibboleth.oidc.security.credential.BasicJWKCredential;
-import net.shibboleth.oidc.security.credential.JWKCredential;
 import net.shibboleth.oidc.security.credential.impl.BasicJOSEObjectCredentialResolver;
-import net.shibboleth.oidc.security.credential.impl.JWKEncryptionCredentialContext;
 import net.shibboleth.oidc.security.impl.BasicJWTDecryptionConfiguration;
 import net.shibboleth.oidc.security.impl.BasicSignatureValidationConfiguration;
 import net.shibboleth.oidc.security.impl.CriterionCredentialResolver;
 import net.shibboleth.oidc.security.impl.ExplicitKeySignedJWTTrustEngine;
-import net.shibboleth.oidc.security.impl.JWSAssemblyUtils;
 import net.shibboleth.utilities.java.support.annotation.constraint.NonnullElements;
 import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
 import net.shibboleth.utilities.java.support.annotation.constraint.Unmodifiable;
@@ -107,7 +99,15 @@ import okhttp3.mockwebserver.MockWebServer;
 import okhttp3.tls.HandshakeCertificates;
 import okhttp3.tls.HeldCertificate;
 
-/** Test the OIDC relying party flow.*/
+/** 
+ * 
+ * Test the OIDC relying party flow.
+ * 
+ * <p>Any test which tests flow execution up to the authentication request controller will use config
+ * in the various XML configuration files. Any test which tests flow execution from the authentication 
+ * request controller will need to setup all required contexts programatically. </p>
+ * 
+ * */
 public class OIDCRPFlowTest extends AbstractAuthnXmlFlowExecutionTests {
     
     private static final String OP_ISSUER_ID = "https://localhost:9918";
@@ -117,6 +117,8 @@ public class OIDCRPFlowTest extends AbstractAuthnXmlFlowExecutionTests {
     
     private final String RP_ALLOWED_ORIGINS = "https://localhost";
     
+    private static final String REDIRECT_URI_OVERRIDE = "https://localhost/callback";
+    
     private static final String CLIENT_ID = "demo_rp";
     
     private static final String CLIENT_SECRET = "Xp2s5v8y/B?E(H+MbQeThWmYq3t6w9z$";
@@ -291,6 +293,8 @@ public class OIDCRPFlowTest extends AbstractAuthnXmlFlowExecutionTests {
     /** Path to the flow to be tested.*/
     @Nonnull private static final String FLOW = 
             "/META-INF/net/shibboleth/idp/flows/authn/OIDCRelyingParty/oidc-relying-party-authn-flow.xml";
+
+    
     
     /** Class logger. */
     @Nonnull private final Logger log = LoggerFactory.getLogger(OIDCRPFlowTest.class);
@@ -354,6 +358,10 @@ public class OIDCRPFlowTest extends AbstractAuthnXmlFlowExecutionTests {
 
         addBeanDefinition(builderContext, "shibboleth.BasicSignatureSigningConfiguration",BeanDefinitionBuilder.
                 genericBeanDefinition(org.opensaml.xmlsec.impl.BasicSignatureSigningConfiguration.class)
+                .setAbstract(true).getBeanDefinition());        
+        
+        addBeanDefinition(builderContext, "shibboleth.BasicEncryptionConfiguration",BeanDefinitionBuilder.
+                genericBeanDefinition(org.opensaml.xmlsec.impl.BasicEncryptionConfiguration.class)
                 .setAbstract(true).getBeanDefinition());
         
         try {
@@ -378,12 +386,14 @@ public class OIDCRPFlowTest extends AbstractAuthnXmlFlowExecutionTests {
   
         loadBeanDefinitionsFromXmlFile(builderContext, 
                 new ClassPathResource("META-INF/net.shibboleth.idp/postconfig.xml"),
-                Map.of("idp.authn.oidc.rp.client.clientId", CLIENT_ID,
-                        "idp.authn.oidc.rp.client.clientSecret",CLIENT_SECRET));
+                null);
         
+        // Note, is the relying-party which loads the profile config in the postconfig.
+        // So properties for the profile config need to go here.
         loadBeanDefinitionsFromXmlFile(builderContext, 
                 new ClassPathResource("conf/test-relyingparty-resolver-service.xml"), 
                 Map.of("idp.authn.oidc.rp.client.clientId", CLIENT_ID,
+                        "idp.authn.oidc.rp.client.redirectURL", REDIRECT_URI_OVERRIDE,
                         "idp.authn.oidc.rp.client.clientSecret",CLIENT_SECRET));
         
         loadBeanDefinitionsFromXmlFile(builderContext, 
@@ -493,8 +503,7 @@ public class OIDCRPFlowTest extends AbstractAuthnXmlFlowExecutionTests {
         final Map<String,String> mockProperties = Map.of(
                 "idp.service.clientinfo.failFast","false",
                 "idp.entityID", "http://idp.example.com/",
-                "idp.authn.oidc.rp.proxyIssuer",OP_ISSUER_ID,
-                "idp.oidc.rp.redirecturl.allowedOrigins", RP_ALLOWED_ORIGINS);
+                "idp.authn.oidc.rp.proxyIssuer",OP_ISSUER_ID);
         
         setMockProperties(mockProperties);
         
@@ -532,8 +541,7 @@ public class OIDCRPFlowTest extends AbstractAuthnXmlFlowExecutionTests {
         final Map<String,String> mockProperties = Map.of(
                 "idp.service.clientinfo.failFast","false",
                 "idp.entityID", "http://idp.example.com/",
-                "idp.authn.oidc.rp.proxyIssuer",OP_ISSUER_ID_REQUESTOBJECT_TRUE,
-                "idp.oidc.rp.redirecturl.allowedOrigins", RP_ALLOWED_ORIGINS);
+                "idp.authn.oidc.rp.proxyIssuer",OP_ISSUER_ID_REQUESTOBJECT_TRUE);
         
         setMockProperties(mockProperties);
         
@@ -566,8 +574,7 @@ public class OIDCRPFlowTest extends AbstractAuthnXmlFlowExecutionTests {
         final Map<String,String> mockProperties = Map.of(
                 "idp.service.clientinfo.failFast","false",
                 "idp.entityID", "http://idp.example.com/",
-                "idp.authn.oidc.rp.proxyIssuer",OP_ISSUER_ID,
-                "idp.oidc.rp.redirecturl.allowedOrigins", RP_ALLOWED_ORIGINS);
+                "idp.authn.oidc.rp.proxyIssuer",OP_ISSUER_ID);
         
         setMockProperties(mockProperties);
         
@@ -661,10 +668,9 @@ public class OIDCRPFlowTest extends AbstractAuthnXmlFlowExecutionTests {
         setFlowModelResources(flowResources);
         setSubflows(subflows);        
         
-        final Map<String,String> mockProperties = Map.of(                
+        final Map<String,String> mockProperties = Map.of(  
                 "idp.entityID", "http://idp.example.com/",
-                "idp.authn.oidc.rp.proxyIssuer",OP_ISSUER_ID,
-                "idp.oidc.rp.redirecturl.allowedOrigins", RP_ALLOWED_ORIGINS);
+                "idp.authn.oidc.rp.proxyIssuer",OP_ISSUER_ID);
         
         setMockProperties(mockProperties);
         
@@ -713,10 +719,9 @@ public class OIDCRPFlowTest extends AbstractAuthnXmlFlowExecutionTests {
         setFlowModelResources(flowResources);
         setSubflows(subflows);        
         
-        final Map<String,String> mockProperties = Map.of(                
+        final Map<String,String> mockProperties = Map.of(   
                 "idp.entityID", "http://idp.example.com/",
-                "idp.authn.oidc.rp.proxyIssuer",OP_ISSUER_ID,
-                "idp.oidc.rp.redirecturl.allowedOrigins", RP_ALLOWED_ORIGINS);
+                "idp.authn.oidc.rp.proxyIssuer",OP_ISSUER_ID);
         
         setMockProperties(mockProperties);
         
@@ -765,8 +770,7 @@ public class OIDCRPFlowTest extends AbstractAuthnXmlFlowExecutionTests {
         
         final Map<String,String> mockProperties = Map.of(
                 "idp.service.clientinfo.failFast","false",
-                "idp.entityID", "http://idp.example.com/",
-                "idp.authn.oidc.rp.proxyIssuer",OP_ISSUER_ID);
+                "idp.entityID", "http://idp.example.com/");
         
         setMockProperties(mockProperties);
         
@@ -814,8 +818,7 @@ public class OIDCRPFlowTest extends AbstractAuthnXmlFlowExecutionTests {
         final Map<String,String> mockProperties = Map.of(
                 "idp.service.clientinfo.failFast","false",
                 "idp.entityID", "http://idp.example.com/",
-                "idp.authn.oidc.rp.proxyIssuer",OP_ISSUER_ID,
-                "idp.oidc.rp.redirecturl.allowedOrigins", RP_ALLOWED_ORIGINS);
+                "idp.authn.oidc.rp.proxyIssuer",OP_ISSUER_ID);
         
         setMockProperties(mockProperties);
         
@@ -946,8 +949,7 @@ public class OIDCRPFlowTest extends AbstractAuthnXmlFlowExecutionTests {
         final Map<String,String> mockProperties = Map.of(
                 "idp.service.clientinfo.failFast","false",
                 "idp.entityID", "http://idp.example.com/",
-                "idp.authn.oidc.rp.proxyIssuer",OP_ISSUER_ID,
-                "idp.oidc.rp.redirecturl.allowedOrigins", RP_ALLOWED_ORIGINS);
+                "idp.authn.oidc.rp.proxyIssuer",OP_ISSUER_ID);
         
         setMockProperties(mockProperties);
         
@@ -1041,8 +1043,7 @@ public class OIDCRPFlowTest extends AbstractAuthnXmlFlowExecutionTests {
         final Map<String,String> mockProperties = Map.of(
                 "idp.service.clientinfo.failFast","false",
                 "idp.entityID", "http://idp.example.com/",
-                "idp.authn.oidc.rp.proxyIssuer",OP_ISSUER_ID,
-                "idp.oidc.rp.redirecturl.allowedOrigins", RP_ALLOWED_ORIGINS);
+                "idp.authn.oidc.rp.proxyIssuer",OP_ISSUER_ID);
         
         setMockProperties(mockProperties);
         
@@ -1098,6 +1099,7 @@ public class OIDCRPFlowTest extends AbstractAuthnXmlFlowExecutionTests {
         partyConfig.setClientCredential(TestCredentialHelper.createClientSecretCredential(CLIENT_SECRET));
         partyConfig.setTokenEndpointAuthMethods(Set.of("client_secret_basic"));
         partyConfig.setClientId(CLIENT_ID);
+        partyConfig.setRedirectUriOverride(REDIRECT_URI_OVERRIDE);
         final RelyingPartyConfiguration rPartyConfig = new RelyingPartyConfiguration();
         rPartyConfig.setResponderId("http://idp.example.com/");
         partyContext.setConfiguration(rPartyConfig);
@@ -1143,8 +1145,7 @@ public class OIDCRPFlowTest extends AbstractAuthnXmlFlowExecutionTests {
         final Map<String,String> mockProperties = Map.of(
                 "idp.service.clientinfo.failFast","false",
                 "idp.entityID", "http://idp.example.com/",
-                "idp.authn.oidc.rp.proxyIssuer",OP_ISSUER_ID,
-                "idp.oidc.rp.redirecturl.allowedOrigins", RP_ALLOWED_ORIGINS);
+                "idp.authn.oidc.rp.proxyIssuer",OP_ISSUER_ID);
         
         setMockProperties(mockProperties);
 
diff --git a/idp-oidc-rp-impl/src/test/resources/conf/test-relying-party-system.xml b/idp-oidc-rp-impl/src/test/resources/conf/test-relying-party-system.xml
index 4cb7807..877092d 100644
--- a/idp-oidc-rp-impl/src/test/resources/conf/test-relying-party-system.xml
+++ b/idp-oidc-rp-impl/src/test/resources/conf/test-relying-party-system.xml
@@ -53,7 +53,8 @@
         <bean id="TestRequestObject" parent="RelyingPartyByName" c:relyingPartyIds="https://localhost:9919">
             <property name="profileConfigurations">
                 <list>
-                    <bean parent="OIDC.SSO" p:useRequestObject="true" p:signRequestObject="true"/>
+                    <bean parent="OIDC.SSO" p:useRequestObject="true" p:signRequestObject="true"
+                    p:encryptRequestObject="false"/>
                 </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