[java-idp-plugin-oidc-rp] branch main updated: Cleanup request object encryption support. Add tests

Phil Smart philip.smart at jisc.ac.uk
Fri Jul 22 13:58:28 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=d03e77f129f455fb8b92c42dfd7daeb6ad43db02

The following commit(s) were added to refs/heads/main by this push:
     new d03e77f  Cleanup request object encryption support. Add tests
d03e77f is described below

commit d03e77f129f455fb8b92c42dfd7daeb6ad43db02
Author: Phil Smart <philip.smart at jisc.ac.uk>
AuthorDate: Fri Jul 22 14:58:22 2022 +0100

    Cleanup request object encryption support. Add tests
---
 ...questObjectEncryptionMethodsLookupFunction.java |  44 ++++
 ...ObjectKeyTransportAlgorithmsLookupFunction.java |  44 ++++
 .../authn/oidc/rp/impl/BuildRequestObject.java     |   2 +-
 .../rp/impl/PopulateJWTEncryptionParameters.java   |   2 +-
 ...oviderMetadataEncryptionParametersResolver.java | 177 +++++++++++++---
 .../authn/oidc/rp/messaging/impl/EncryptJWT.java   |   2 -
 .../oidc-relying-party-authn-beans.xml             |  11 +-
 .../plugin/authn/oidc/rp/impl/OIDCRPFlowTest.java  |  14 +-
 ...erMetadataEncryptionParametersResolverTest.java | 233 +++++++++++++++++++++
 .../plugin/authn/oidc/rp/impl/TestJsonHelper.java  |  55 +++++
 .../flow/AbstractAuthnXmlFlowExecutionTests.java   |  21 +-
 ...st-provider-resolver-remote-jwkset-response.jwk |  66 ++++++
 .../src/test/resources/logback-test.xml            |   3 +-
 .../test-resolver-provider-encryption.json         |  89 ++++++++
 14 files changed, 698 insertions(+), 65 deletions(-)

diff --git a/idp-oidc-rp-api/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/config/navigate/ProviderRequestObjectEncryptionMethodsLookupFunction.java b/idp-oidc-rp-api/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/config/navigate/ProviderRequestObjectEncryptionMethodsLookupFunction.java
new file mode 100644
index 0000000..a784db9
--- /dev/null
+++ b/idp-oidc-rp-api/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/config/navigate/ProviderRequestObjectEncryptionMethodsLookupFunction.java
@@ -0,0 +1,44 @@
+/*
+ * 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.Collections;
+import java.util.List;
+import java.util.function.Function;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import com.nimbusds.jose.EncryptionMethod;
+import com.nimbusds.openid.connect.sdk.op.OIDCProviderMetadata;
+
+/** Lookup the request_object_encryption_alg_values_supported from the provider metadata.*/
+public class ProviderRequestObjectEncryptionMethodsLookupFunction 
+                implements Function<OIDCProviderMetadata, List<EncryptionMethod>> {
+
+    @Override
+    @Nonnull public List<EncryptionMethod> apply(@Nullable final OIDCProviderMetadata metadata) {        
+        if (metadata == null) {
+            return Collections.emptyList();
+        }
+        return metadata.getRequestObjectJWEEncs() != null 
+                ? metadata.getRequestObjectJWEEncs() : Collections.emptyList();
+        
+    }
+
+}
diff --git a/idp-oidc-rp-api/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/config/navigate/ProviderRequestObjectKeyTransportAlgorithmsLookupFunction.java b/idp-oidc-rp-api/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/config/navigate/ProviderRequestObjectKeyTransportAlgorithmsLookupFunction.java
new file mode 100644
index 0000000..426c2a7
--- /dev/null
+++ b/idp-oidc-rp-api/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/config/navigate/ProviderRequestObjectKeyTransportAlgorithmsLookupFunction.java
@@ -0,0 +1,44 @@
+/*
+ * 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.Collections;
+import java.util.List;
+import java.util.function.Function;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import com.nimbusds.jose.JWEAlgorithm;
+import com.nimbusds.openid.connect.sdk.op.OIDCProviderMetadata;
+
+/** Lookup the request_object_encryption_enc_values_supported from the provider metadata.*/
+public class ProviderRequestObjectKeyTransportAlgorithmsLookupFunction 
+                implements Function<OIDCProviderMetadata, List<JWEAlgorithm>> {
+
+    @Override
+    @Nonnull public List<JWEAlgorithm> apply(@Nullable final OIDCProviderMetadata metadata) {
+        if (metadata == null) {
+            return Collections.emptyList();
+        }
+        return metadata.getRequestObjectJWEAlgs() != null 
+                ? metadata.getRequestObjectJWEAlgs() : Collections.emptyList();
+        
+    }
+
+}
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 bb77907..45cf1b7 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
@@ -154,7 +154,7 @@ public class BuildRequestObject extends AbstractOIDCAuthenticationRequestAction
                     requestObjectClaims.toJSONString());
         }
         
-        // Create a plain JWT at first, can be signed and encrypted later        
+        // Create the claim first, can be signed and encrypted as a JWT later        
         authnRequest.setRequestObjectClaimsSet(requestObjectClaims);
                
     }
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
index 1c78a66..fc8bef0 100644
--- 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
@@ -302,7 +302,7 @@ public class PopulateJWTEncryptionParameters extends AbstractProfileAction {
             log.debug("{} OIDCProviderMetadataContext is absent", getLogPrefix());
         }
         
-        // Add any static credentials from the RP context
+        // Add any static credentials from the RP context. If any resolver supports it
         final RelyingPartyContext rpCtx = 
                 relyingPartyContextLookupStrategy.apply(profileRequestContext);     
         if (rpCtx != null && rpCtx.getConfiguration() != null &&
diff --git a/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/ProviderMetadataEncryptionParametersResolver.java b/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/ProviderMetadataEncryptionParametersResolver.java
index ddce8f0..0e117fd 100644
--- a/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/ProviderMetadataEncryptionParametersResolver.java
+++ b/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/ProviderMetadataEncryptionParametersResolver.java
@@ -1,9 +1,28 @@
+/*
+ * 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.security.NoSuchAlgorithmException;
 import java.time.Duration;
 import java.time.Instant;
 import java.util.Collections;
 import java.util.List;
+import java.util.function.Function;
 import java.util.function.Predicate;
 import java.util.stream.Collectors;
 
@@ -32,16 +51,29 @@ import net.shibboleth.oidc.jwk.RemoteJwkSetCache;
 import net.shibboleth.oidc.security.credential.BasicJWKCredential;
 import net.shibboleth.oidc.security.criterion.ProviderMetadataCriterion;
 import net.shibboleth.oidc.security.criterion.StaticCredentialCriterion;
+import net.shibboleth.oidc.security.impl.OIDCDecryptionParameters;
+import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
 import net.shibboleth.utilities.java.support.annotation.constraint.Positive;
 import net.shibboleth.utilities.java.support.logic.Constraint;
+import net.shibboleth.utilities.java.support.logic.FunctionSupport;
+import net.shibboleth.utilities.java.support.logic.PredicateSupport;
 import net.shibboleth.utilities.java.support.resolver.CriteriaSet;
 
-//TODO so far, this is only pulling out request object algs. Use a strategy to make it generic
+/**
+ * 
+ * <p>Does not support Direct Encryption.</p>
+ */
 public class ProviderMetadataEncryptionParametersResolver extends BasicEncryptionParametersResolver {
     
     /** Logger. */
     private final Logger log = LoggerFactory.getLogger(ProviderMetadataEncryptionParametersResolver.class);
     
+    /** A strategy to locate the encryption methods ('enc') appropriate for the JWT to be encrypted.*/
+    @Nonnull private Function<OIDCProviderMetadata, List<EncryptionMethod>> providerEncryptionMethodsLookupStrategy;
+    
+    /** A strategy to locate the algorithms ('alg') appropriate for the JWT to be encrypted.*/
+    @Nonnull private Function<OIDCProviderMetadata, List<JWEAlgorithm>> providerKeyTransportAlgorithmsLookupStrategy;
+    
     /** The cache for remote JWK key sets. */
     @Nullable private RemoteJwkSetCache remoteJwkSetCache;
     
@@ -52,8 +84,35 @@ public class ProviderMetadataEncryptionParametersResolver extends BasicEncryptio
     /** Constructor.*/
     public ProviderMetadataEncryptionParametersResolver() {
         super();
+        providerEncryptionMethodsLookupStrategy = FunctionSupport.constant(Collections.emptyList());
+        providerKeyTransportAlgorithmsLookupStrategy = FunctionSupport.constant(Collections.emptyList());
     }
     
+    /**
+     * Set the strategy used to locate the algorothms ('alg') from the OpenID Provider metadata
+     * appropriate for the JWT to be encrypted.
+     *     
+     * @param strategy the strategy
+     */
+    public void setProviderKeyTransportAlgorithmsLookupStrategy(
+            @Nonnull final Function<OIDCProviderMetadata, List<JWEAlgorithm>> strategy) {
+
+        providerKeyTransportAlgorithmsLookupStrategy = Constraint.isNotNull(strategy,
+                "ProviderAlgorithmsLookupStrategy can not be null");
+    }
+    
+    /**
+     * Set the strategy used to locate the encryption methods ('enc') from the OpenID Provider metadata
+     * appropriate for the JWT to be encrypted.
+     *     
+     * @param strategy the strategy
+     */
+    public void setProviderEncryptionMethodsLookupStrategy(
+            @Nonnull final Function<OIDCProviderMetadata, List<EncryptionMethod>> strategy) {
+
+        providerEncryptionMethodsLookupStrategy = Constraint.isNotNull(strategy,
+                "ProviderEncryptionMethodsLookupStrategy can not be null");
+    }
     
     /**
      * Set the cache for remote JWK key sets.
@@ -91,19 +150,17 @@ public class ProviderMetadataEncryptionParametersResolver extends BasicEncryptio
         final OIDCProviderMetadata metadata = criteria.get(ProviderMetadataCriterion.class).getMetadata();
         
         // We populate the parameters for the algorithm the provider has registered
-        final List<JWEAlgorithm> keyTransportAlgorithms =  metadata.getRequestObjectJWEAlgs() !=null 
-                ? metadata.getRequestObjectJWEAlgs(): Collections.emptyList();        
+        final List<JWEAlgorithm> keyTransportAlgorithms =  
+                providerKeyTransportAlgorithmsLookupStrategy.apply(metadata);      
         log.trace("Resolved effective key transport algorithms from provider metadata: {}", keyTransportAlgorithms);
         if (keyTransportAlgorithms.isEmpty()) {
             log.debug("No algorithm information in provider metadata, falling back to default configuration");
             super.resolveAndPopulateCredentialsAndAlgorithms(params, criteria, includeExcludePredicate);
             return;
-        }
-        
-        //TODO use strategy to pull these out
-        final List<EncryptionMethod> dataEncryptionMethods = metadata.getRequestObjectJWEEncs() != null ? 
-                metadata.getRequestObjectJWEEncs() : Collections.emptyList();
+        }        
         
+        final List<EncryptionMethod> dataEncryptionMethods = 
+                providerEncryptionMethodsLookupStrategy.apply(metadata);        
         log.trace("Resolved effective data encryption algorithms from provider metadata: {}", dataEncryptionMethods);
         
         final List<String> keyTransportAlgorithmSupported =
@@ -129,36 +186,67 @@ public class ProviderMetadataEncryptionParametersResolver extends BasicEncryptio
         log.debug("Supported and configured data encryption algorithms: {}", 
                 supportedAndConfiguredDataEncryptionAlgorithms);
         
+        if (supportedAndConfiguredKeyTransportAlgorithms.isEmpty()) {
+            log.warn("No supported key transport algorithm");
+            super.resolveAndPopulateCredentialsAndAlgorithms(params, criteria, includeExcludePredicate);
+            return;
+        }
+        if (supportedAndConfiguredDataEncryptionAlgorithms.isEmpty()) {
+            log.warn("No supported data encryption method");
+            super.resolveAndPopulateCredentialsAndAlgorithms(params, criteria, includeExcludePredicate);
+            return;
+        }
+        
+        final List<JWEAlgorithm> supportedJWEKeyTransportAlgorithms = 
+                convertStringAlgorithmURIsToJwkAlgorithms(supportedAndConfiguredKeyTransportAlgorithms);
+            
+        final EncryptionMethod encryptionMethod = 
+                resolveEncryptionMethod(supportedAndConfiguredDataEncryptionAlgorithms);
+        if (encryptionMethod == null) {
+            log.warn("No supported encryption method");
+            super.resolveAndPopulateCredentialsAndAlgorithms(params, criteria, includeExcludePredicate);
+            return;
+        } 
+        
+        //Check if all supported and configured 'alg's are key wrapping algorithms. If so, use
+        //Key wrapping, otherwise chose a key encryption/agreement algorithm.
+        if (allKeyWrappingAlgorithms(supportedJWEKeyTransportAlgorithms)) {
+            //Do key wrapping
+            log.debug("All configured and supported algorithms are for the key wrapping mode, generating"
+                    + " key wrapping credential");
+            // Choose the first algorithm
+            final JWEAlgorithm algorithm = supportedJWEKeyTransportAlgorithms.get(0);
+            // Pull out the shared secret from the config?
+            //TODO check this logic
+            if (criteria.contains(StaticCredentialCriterion.class)) {
+                final Credential sharedSecret = criteria.get(StaticCredentialCriterion.class).getCredential();
+                //Do more here.
+                params.setKeyTransportEncryptionCredential(sharedSecret);
+                params.setKeyTransportEncryptionAlgorithm(algorithm.getName());
+                params.setDataEncryptionAlgorithm(encryptionMethod.getName());
+                return;
+            } else {
+                log.warn("No shared secret criterion found, can not generate key wrapping credential");
+                super.resolveAndPopulateCredentialsAndAlgorithms(params, criteria, includeExcludePredicate);
+                return;
+            }
+            
+        }
         
+        // Find and process key encryption or key agreement modes
         JWKSet providerKeySet = getProviderKeys(metadata);
         if (providerKeySet == null) {
             providerKeySet = new JWKSet();
         }
         log.trace("Has '{}' keys from provider's JWKSet", providerKeySet.getKeys().size());
-
-        // Add any static credentials from the criteria. Add as a data encryption credential e.g for Direct Encryption.
-        //TODO we need to consider this for the 'dir' alg.
-        if (criteria.contains(StaticCredentialCriterion.class)) {
-            final Credential staticCred = criteria.get(StaticCredentialCriterion.class).getCredential();
-            log.trace("Signing credential found in criterion '{}'", staticCred.getKeyNames());
-            if (staticCred.getSecretKey() != null) {
-                //dataEncryptionCredentials.add(staticCred);
-            }
-        }
-        
-        final List<JWEAlgorithm> supportedJWEKeyTransportAlgorithms = 
-                convertSupportAlgorithmsToJwkAlgorithms(supportedAndConfiguredKeyTransportAlgorithms);
-        
-        // Default encEnc value      
-        // TODO we need to 'chose' this.
-        final EncryptionMethod encryptionMethod = EncryptionMethod.A128CBC_HS256;
         
-        // Keys in the remote keys file are keytransport algorithms?
+        // Keys in the remote keys file are key encryption and agreement algorithms?
         for (final JWK key : providerKeySet.getKeys()) {
             if (KeyUse.SIGNATURE.equals(key.getKeyUse())) {
                 continue;
             }
-            final JWEAlgorithm keyTransportAlgorithm = findSupportedAlgorithm(key, supportedJWEKeyTransportAlgorithms);
+            final JWEAlgorithm keyTransportAlgorithm = 
+                    findSupportedKeyTransportAlgorithm(key, supportedJWEKeyTransportAlgorithms);
             if (keyTransportAlgorithm != null) {
                 final BasicJWKCredential jwkCredential = new BasicJWKCredential();
                 jwkCredential.setAlgorithm(keyTransportAlgorithm);
@@ -186,6 +274,32 @@ public class ProviderMetadataEncryptionParametersResolver extends BasicEncryptio
 
     }
     
+    /**
+     * If all the supported algorithms are symmetric key wrapping algorithms, return true. Return false otherwise.
+     * 
+     * @param algorithms the alogorithms to check
+     * 
+     * @return true if all algorithms are symmetric key wrapping algorithms, false otherwise.
+     */
+    private boolean allKeyWrappingAlgorithms(@Nonnull @NotEmpty final List<JWEAlgorithm> algorithms) {
+        return algorithms.stream().allMatch(
+                PredicateSupport.or(JWEAlgorithm.Family.AES_GCM_KW::contains, JWEAlgorithm.Family.AES_KW::contains));
+    }
+
+    /**
+     * Return the first encryption method in the supported list, or null otherwise.
+     * 
+     * @param dataEncryptionAlgorithms the supported data encryption method
+     * 
+     * @return the first supported encryption method, or {@literal null}.
+     */
+    @Nullable private EncryptionMethod resolveEncryptionMethod(@Nonnull final List<String> dataEncryptionAlgorithms) {
+        if (!dataEncryptionAlgorithms.isEmpty()) {
+            return EncryptionMethod.parse(dataEncryptionAlgorithms.get(0));
+        } 
+        return null;
+    }
+    
     /**
      * Convert the algorithms represented as strings, into Nimbus {@link Algorithm}s for later comparison.
      * 
@@ -193,20 +307,21 @@ public class ProviderMetadataEncryptionParametersResolver extends BasicEncryptio
      * 
      * @return the converted algorithms
      */
-    @Nonnull private List<JWEAlgorithm> convertSupportAlgorithmsToJwkAlgorithms(@Nonnull final List<String> algos) {
+    @Nonnull private List<JWEAlgorithm> convertStringAlgorithmURIsToJwkAlgorithms(@Nonnull final List<String> algos) {
         return algos.stream().map(JWEAlgorithm::parse).collect(Collectors.toList());
     }
     
     /**
-     * Does the key support any one of the given algorithms. 
+     * Does the key support any one of the given algorithms. The key has to be either an RSA, or EC type.
      * 
      * @param key the key to check
      * @param algorithms the algorithms to check against
      * 
      * @return the supported algorithm, or null if none are supported
      */
-    @Nullable private JWEAlgorithm findSupportedAlgorithm(@Nonnull final JWK key, 
-            @Nonnull final List<JWEAlgorithm> algorithms) {        
+    @Nullable private JWEAlgorithm findSupportedKeyTransportAlgorithm(@Nonnull final JWK key, 
+            @Nonnull final List<JWEAlgorithm> algorithms) {  
+        
         final JWEAlgorithm algorithm =
                 algorithms.stream().filter(alg -> alg.equals(key.getAlgorithm())).findFirst().orElse(null);
         
diff --git a/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/messaging/impl/EncryptJWT.java b/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/messaging/impl/EncryptJWT.java
index e27fd36..60616a4 100644
--- a/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/messaging/impl/EncryptJWT.java
+++ b/idp-oidc-rp-impl/src/main/java/net/shibboleth/idp/plugin/authn/oidc/rp/messaging/impl/EncryptJWT.java
@@ -29,11 +29,9 @@ import javax.annotation.Nullable;
 
 import org.opensaml.messaging.context.MessageContext;
 import org.opensaml.messaging.context.navigate.ChildContextLookup;
-import org.opensaml.messaging.context.navigate.RecursiveTypedParentContextLookup;
 import org.opensaml.messaging.handler.AbstractMessageHandler;
 import org.opensaml.messaging.handler.MessageHandler;
 import org.opensaml.messaging.handler.MessageHandlerException;
-import org.opensaml.profile.context.ProfileRequestContext;
 import org.opensaml.security.credential.Credential;
 import org.opensaml.xmlsec.EncryptionParameters;
 import org.opensaml.xmlsec.context.SecurityParametersContext;
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 e82f0e6..29e010f 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
@@ -217,8 +217,15 @@
 
     <bean id="shibboleth.authn.oidc.rp.EncryptionParametersResolver"
         class="net.shibboleth.idp.plugin.authn.oidc.rp.impl.ProviderMetadataEncryptionParametersResolver"
-        p:remoteJwkSetCache-ref="shibboleth.authn.oidc.rp.RemoteJwkSetCache"/>
-    
+        p:remoteJwkSetCache-ref="shibboleth.authn.oidc.rp.RemoteJwkSetCache">
+        <property name="providerEncryptionMethodsLookupStrategy">
+            <bean class="net.shibboleth.idp.plugin.authn.oidc.rp.config.navigate.ProviderRequestObjectEncryptionMethodsLookupFunction"/>
+        </property>
+        <property name="providerKeyTransportAlgorithmsLookupStrategy">
+            <bean class="net.shibboleth.idp.plugin.authn.oidc.rp.config.navigate.ProviderRequestObjectKeyTransportAlgorithmsLookupFunction"/>
+        </property>
+    </bean>
+        
     
     <bean id="BuildRequestObject" class="net.shibboleth.idp.plugin.authn.oidc.rp.impl.BuildRequestObject"
         scope="prototype" p:profileContextLookupStrategy-ref="shibboleth.ChildLookup.ProxyProfileRequestContext"
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 f7e75b3..e0d794f 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
@@ -362,7 +362,7 @@ public class OIDCRPFlowTest extends AbstractAuthnXmlFlowExecutionTests {
     private OIDCPeerEntityContext createPeerContext() throws ParseException {
         final OIDCPeerEntityContext peerCtx = new OIDCPeerEntityContext();
         final OIDCProviderMetadata providerMetadata = 
-                OIDCProviderMetadata.parse(readJsonFromFile(GOOD_PROVIDER_CONFIGURATION_INFO));
+                OIDCProviderMetadata.parse(TestJsonHelper.readJsonFromFile(GOOD_PROVIDER_CONFIGURATION_INFO));
         final OIDCProviderMetadataContext providerMetadataCtx = new OIDCProviderMetadataContext();
         providerMetadataCtx.setProviderInformation(providerMetadata);
         peerCtx.addSubcontext(providerMetadataCtx);
@@ -430,7 +430,7 @@ public class OIDCRPFlowTest extends AbstractAuthnXmlFlowExecutionTests {
         // First is metadata exchange
         mockOPServer.enqueue(new MockResponse().setResponseCode(200)
                 .setHeader("content-type", "application/json")
-                .setBody(readJsonFromFile(GOOD_PROVIDER_CONFIGURATION_INFO)));
+                .setBody(TestJsonHelper.readJsonFromFile(GOOD_PROVIDER_CONFIGURATION_INFO)));
        
         mockOPServer.start(9918);
         
@@ -468,7 +468,7 @@ public class OIDCRPFlowTest extends AbstractAuthnXmlFlowExecutionTests {
         // First is metadata exchange
         mockOPServer.enqueue(new MockResponse().setResponseCode(200)
                 .setHeader("content-type", "application/json")
-                .setBody(readJsonFromFile(GOOD_PROVIDER_CONFIGURATION_INFO_USE_REQUEST_OBJECT)));
+                .setBody(TestJsonHelper.readJsonFromFile(GOOD_PROVIDER_CONFIGURATION_INFO_USE_REQUEST_OBJECT)));
        
         mockOPServer.start(9919);
         
@@ -507,12 +507,12 @@ public class OIDCRPFlowTest extends AbstractAuthnXmlFlowExecutionTests {
         // First is metadata exchange
         mockOPServer.enqueue(new MockResponse().setResponseCode(200)
                 .setHeader("content-type", "application/json")
-                .setBody(readJsonFromFile(GOOD_PROVIDER_CONFIGURATION_INFO_USE_REQUEST_OBJECT_ENCRYPT)));
+                .setBody(TestJsonHelper.readJsonFromFile(GOOD_PROVIDER_CONFIGURATION_INFO_USE_REQUEST_OBJECT_ENCRYPT)));
         
         // Second is JWKSet lookup
         mockOPServer.enqueue(new MockResponse().setResponseCode(200)
                 .setHeader("content-type", "application/json")
-                .setBody(readJsonFromFile(REMOTE_JWKSET_RESPONSE)));
+                .setBody(TestJsonHelper.readJsonFromFile(REMOTE_JWKSET_RESPONSE)));
        
         mockOPServer.start(9921);
         
@@ -550,7 +550,7 @@ public class OIDCRPFlowTest extends AbstractAuthnXmlFlowExecutionTests {
         // First is metadata exchange
         mockOPServer.enqueue(new MockResponse().setResponseCode(200)
                 .setHeader("content-type", "application/json")
-                .setBody(readJsonFromFile(GOOD_PROVIDER_CONFIGURATION_INFO_USE_REQUEST_OBJECT_RSA256_SIG)));
+                .setBody(TestJsonHelper.readJsonFromFile(GOOD_PROVIDER_CONFIGURATION_INFO_USE_REQUEST_OBJECT_RSA256_SIG)));
        
         mockOPServer.start(9920);
         
@@ -583,7 +583,7 @@ public class OIDCRPFlowTest extends AbstractAuthnXmlFlowExecutionTests {
         // First is metadata exchange
         mockOPServer.enqueue(new MockResponse().setResponseCode(200)
                 .setHeader("content-type", "application/json")
-                .setBody(readJsonFromFile(GOOD_PROVIDER_CONFIGURATION_INFO)));
+                .setBody(TestJsonHelper.readJsonFromFile(GOOD_PROVIDER_CONFIGURATION_INFO)));
        
         mockOPServer.start(9918);
         
diff --git a/idp-oidc-rp-impl/src/test/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/ProviderMetadataEncryptionParametersResolverTest.java b/idp-oidc-rp-impl/src/test/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/ProviderMetadataEncryptionParametersResolverTest.java
new file mode 100644
index 0000000..21a653f
--- /dev/null
+++ b/idp-oidc-rp-impl/src/test/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/ProviderMetadataEncryptionParametersResolverTest.java
@@ -0,0 +1,233 @@
+/*
+ * 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 static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
+
+import java.io.IOException;
+import java.util.List;
+
+import org.apache.http.HttpResponse;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpUriRequest;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.protocol.HttpContext;
+import org.mockito.Mockito;
+import org.opensaml.core.config.InitializationException;
+import org.opensaml.storage.StorageService;
+import org.opensaml.storage.impl.MemoryStorageService;
+import org.opensaml.xmlsec.EncryptionParameters;
+import org.opensaml.xmlsec.config.GlobalAlgorithmRegistryInitializer;
+import org.opensaml.xmlsec.criterion.EncryptionConfigurationCriterion;
+import org.opensaml.xmlsec.impl.BasicEncryptionConfiguration;
+import org.springframework.core.io.ClassPathResource;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.nimbusds.openid.connect.sdk.op.OIDCProviderMetadata;
+
+import net.shibboleth.oidc.jwa.support.EncryptionConstants;
+import net.shibboleth.oidc.jwa.support.KeyManagementConstants;
+import net.shibboleth.oidc.jwk.RemoteJwkSetCache;
+import net.shibboleth.oidc.security.criterion.ProviderMetadataCriterion;
+import net.shibboleth.oidc.security.criterion.StaticCredentialCriterion;
+import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
+import net.shibboleth.utilities.java.support.resolver.CriteriaSet;
+
+/** Tests for the {@link ProviderMetadataEncryptionParametersResolver}.*/
+public class ProviderMetadataEncryptionParametersResolverTest {
+    
+    /**
+     * Example of good provider metadata that supports request_object_encryption.
+     */
+    private static final ClassPathResource GOOD_PROVIDER_CONFIGURATION_INFO = 
+            new ClassPathResource("/metadata/test-resolver-provider-encryption.json");
+    
+    /** A remote JWKSet.*/
+    private static final ClassPathResource REMOTE_JWKSET = 
+            new ClassPathResource("/conf/credentials/test-provider-resolver-remote-jwkset-response.jwk");    
+    
+    /** The client_secret.*/
+    private static final String CLIENT_SECRET = "Xp2s5v8y/B?E(H+MbQeThWmYq3t6w9z$";
+    
+    /** The resolver to test.*/
+    private ProviderMetadataEncryptionParametersResolver resolver;
+    
+    /** The basic config.*/
+    private BasicEncryptionConfiguration config;
+    
+
+    @BeforeMethod
+    public void setup() throws ComponentInitializationException, ClientProtocolException, IOException {
+        resolver = new ProviderMetadataEncryptionParametersResolver();
+        resolver.setProviderEncryptionMethodsLookupStrategy(OIDCProviderMetadata::getRequestObjectJWEEncs);
+        resolver.setProviderKeyTransportAlgorithmsLookupStrategy(OIDCProviderMetadata::getRequestObjectJWEAlgs);
+        final RemoteJwkSetCache cache = new RemoteJwkSetCache();
+        cache.setStorage(buildStorageService());
+        cache.setHttpClient(createMockHttpClient(TestJsonHelper.readJsonFromFile(REMOTE_JWKSET)));
+        resolver.setRemoteJwkSetCache(cache);
+    }
+    
+    protected HttpClient createMockHttpClient(final String output) throws ClientProtocolException, IOException {
+        final HttpClient httpClient = Mockito.mock(HttpClient.class);
+        final HttpResponse httpResponse = Mockito.mock(HttpResponse.class);
+        Mockito.when(httpResponse.getEntity()).thenReturn(new StringEntity(output));
+        Mockito.when(httpClient.execute((HttpUriRequest) Mockito.any(), 
+                (HttpContext) Mockito.any())).thenReturn(httpResponse);
+        return httpClient;
+    }
+    
+    private StorageService buildStorageService() throws ComponentInitializationException {
+        final MemoryStorageService storageService = new MemoryStorageService();
+        storageService.setId("mockId");
+        storageService.initialize();
+        return storageService;
+    }
+    
+    private CriteriaSet buildBasicCriteriaSet() throws Exception {
+        
+        //Create an algorithm registry here, as opensaml init will not take place for these tests      
+        try {
+            final GlobalAlgorithmRegistryInitializer gar = new GlobalAlgorithmRegistryInitializer();
+            gar.init();
+        } catch (final InitializationException e) {
+            fail();
+        }
+        
+        config = new BasicEncryptionConfiguration();
+        config.setKeyTransportEncryptionAlgorithms(
+                List.of(KeyManagementConstants.ALGO_ID_ALG_AES_128_KW, KeyManagementConstants.ALGO_ID_ALG_RSA_OAEP_256,
+                KeyManagementConstants.ALGO_ID_ALG_ECDH_ES_AES_192_KW, KeyManagementConstants.ALGO_ID_ALG_RSA_OAEP));
+        config.setDataEncryptionAlgorithms(
+                List.of(EncryptionConstants.ALGO_ID_ENC_ALG_A128CBC_HS256,EncryptionConstants.ALGO_ID_ENC_ALG_A128GCM,
+                        EncryptionConstants.ALGO_ID_ENC_ALG_A256CBC_HS512));
+        final CriteriaSet criteria = new CriteriaSet(new EncryptionConfigurationCriterion(List.of(config)));
+        criteria.add(new ProviderMetadataCriterion(
+                OIDCProviderMetadata.parse(TestJsonHelper.readJsonFromFile(GOOD_PROVIDER_CONFIGURATION_INFO))));
+        criteria.add(
+                new StaticCredentialCriterion(TestCredentialHelper.createClientSecretCredential(CLIENT_SECRET)));
+        return criteria;
+    }
+    
+    @Test
+    public void testSuccessfulResolution() throws Exception {
+        final Iterable<EncryptionParameters> params = resolver.resolve(buildBasicCriteriaSet());
+        assertNotNull(params);
+        assertTrue(params.iterator().hasNext());
+        final EncryptionParameters param = params.iterator().next();
+        assertNotNull(param.getDataEncryptionAlgorithm());
+        assertNotNull(param.getKeyTransportEncryptionAlgorithm()); 
+        assertNotNull(param.getKeyTransportEncryptionCredential());
+        assertNotNull(param.getKeyTransportEncryptionCredential().getPublicKey());
+    }
+    
+    /* Algorithms are know because they are limited by config.*/
+    @Test
+    public void testSuccessfulResolution_WithKnownAlgorithms() throws Exception {
+        final CriteriaSet criteria =  buildBasicCriteriaSet();
+        config.setKeyTransportEncryptionAlgorithms(List.of(KeyManagementConstants.ALGO_ID_ALG_RSA_OAEP));
+        config.setDataEncryptionAlgorithms(List.of(EncryptionConstants.ALGO_ID_ENC_ALG_A256CBC_HS512));
+        
+        final Iterable<EncryptionParameters> params = resolver.resolve(criteria);
+        assertNotNull(params);
+        assertTrue(params.iterator().hasNext());
+        final EncryptionParameters param = params.iterator().next();
+        assertNotNull(param.getDataEncryptionAlgorithm());
+        assertNotNull(param.getKeyTransportEncryptionAlgorithm());  
+        assertEquals(param.getDataEncryptionAlgorithm(),EncryptionConstants.ALGO_ID_ENC_ALG_A256CBC_HS512);
+        assertEquals(param.getKeyTransportEncryptionAlgorithm(),KeyManagementConstants.ALGO_ID_ALG_RSA_OAEP);
+        assertNotNull(param.getKeyTransportEncryptionCredential());
+        assertNotNull(param.getKeyTransportEncryptionCredential().getPublicKey());
+    }
+    
+    @Test
+    public void testSuccessfulResolution_ForKeyWrap() throws Exception {
+        final CriteriaSet criteria =  buildBasicCriteriaSet();
+        config.setKeyTransportEncryptionAlgorithms(List.of(KeyManagementConstants.ALGO_ID_ALG_AES_256_KW));
+        config.setDataEncryptionAlgorithms(List.of(EncryptionConstants.ALGO_ID_ENC_ALG_A128GCM));
+        
+        final Iterable<EncryptionParameters> params = resolver.resolve(criteria);
+        assertNotNull(params);
+        assertTrue(params.iterator().hasNext());
+        final EncryptionParameters param = params.iterator().next();
+        assertNotNull(param.getDataEncryptionAlgorithm());
+        assertNotNull(param.getKeyTransportEncryptionAlgorithm());  
+        assertEquals(param.getDataEncryptionAlgorithm(),EncryptionConstants.ALGO_ID_ENC_ALG_A128GCM);
+        assertEquals(param.getKeyTransportEncryptionAlgorithm(),KeyManagementConstants.ALGO_ID_ALG_AES_256_KW);
+        assertNotNull(param.getKeyTransportEncryptionCredential());
+        assertNotNull(param.getKeyTransportEncryptionCredential().getSecretKey());
+    }
+    
+    /* 
+     * Can not test ECDH-ES as the net.shibboleth.oidc.jwa.algorithm.descriptors.KeyAgreementECDHES is not
+     * supported by the runtime!
+     */
+    @Test(enabled = false)
+    public void testSuccessfulResolution_ForKeyAgreement() throws Exception {
+        final CriteriaSet criteria =  buildBasicCriteriaSet();
+        config.setKeyTransportEncryptionAlgorithms(List.of(KeyManagementConstants.ALGO_ID_ALG_ECDH_ES));
+        config.setDataEncryptionAlgorithms(List.of(EncryptionConstants.ALGO_ID_ENC_ALG_A128GCM));
+        
+        final Iterable<EncryptionParameters> params = resolver.resolve(criteria);
+        assertNotNull(params);
+        assertTrue(params.iterator().hasNext());
+        final EncryptionParameters param = params.iterator().next();
+        assertNotNull(param.getDataEncryptionAlgorithm());
+        assertNotNull(param.getKeyTransportEncryptionAlgorithm());  
+        assertEquals(param.getDataEncryptionAlgorithm(),EncryptionConstants.ALGO_ID_ENC_ALG_A128GCM);
+        assertEquals(param.getKeyTransportEncryptionAlgorithm(),KeyManagementConstants.ALGO_ID_ALG_ECDH_ES);
+        assertNotNull(param.getDataEncryptionCredential());
+        assertNotNull(param.getDataEncryptionCredential().getPublicKey());
+    }
+    
+    @Test
+    public void testUnSuccessfulResolution_NoSupportedKeyTransportAlgorithm() throws Exception {
+        final CriteriaSet criteria =  buildBasicCriteriaSet();
+        config.setKeyTransportEncryptionAlgorithms(List.of("NOT-SUPPORTED"));
+        
+        final Iterable<EncryptionParameters> params = resolver.resolve(criteria);
+        assertNotNull(params);
+        assertFalse(params.iterator().hasNext());
+    }
+    
+    @Test
+    public void testUnSuccessfulResolution_OnlyConfigCriterion() throws Exception {
+        buildBasicCriteriaSet();
+        final CriteriaSet criteria =  new CriteriaSet(new EncryptionConfigurationCriterion(List.of(config)));
+        
+        final Iterable<EncryptionParameters> params = resolver.resolve(criteria);
+        assertNotNull(params);
+        assertFalse(params.iterator().hasNext());
+    }
+    
+    @Test
+    public void testUnSuccessfulResolution_NoSupportedDataEncryptionMethod() throws Exception {
+        final CriteriaSet criteria =  buildBasicCriteriaSet();
+        config.setDataEncryptionAlgorithms(List.of("NOT-SUPPORTED"));
+        
+        final Iterable<EncryptionParameters> params = resolver.resolve(criteria);
+        assertNotNull(params);
+        assertFalse(params.iterator().hasNext());
+    }
+
+}
diff --git a/idp-oidc-rp-impl/src/test/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/TestJsonHelper.java b/idp-oidc-rp-impl/src/test/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/TestJsonHelper.java
new file mode 100644
index 0000000..157250a
--- /dev/null
+++ b/idp-oidc-rp-impl/src/test/java/net/shibboleth/idp/plugin/authn/oidc/rp/impl/TestJsonHelper.java
@@ -0,0 +1,55 @@
+/*
+ * 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 static org.testng.Assert.fail;
+
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.nio.charset.StandardCharsets;
+
+import javax.annotation.Nonnull;
+
+import org.springframework.core.io.Resource;
+import org.springframework.util.FileCopyUtils;
+
+/** Helper methods for dealing with JSON.*/
+public final class TestJsonHelper {
+    
+    private TestJsonHelper() {
+        
+    }
+    
+    /**
+     * Read a file into a string.
+     * 
+     * @param location the location of the file to read
+     * 
+     * @return the file as a string
+     */
+    public static String readJsonFromFile(@Nonnull final Resource location) {
+        try (Reader reader = new InputStreamReader(location.getInputStream(), StandardCharsets.UTF_8)) {
+            return FileCopyUtils.copyToString(reader);
+        } catch (final Exception ex) {
+            fail();
+            return null;
+        }
+    }
+
+}
diff --git a/idp-oidc-rp-impl/src/test/java/net/shibboleth/idp/plugin/authn/test/flow/AbstractAuthnXmlFlowExecutionTests.java b/idp-oidc-rp-impl/src/test/java/net/shibboleth/idp/plugin/authn/test/flow/AbstractAuthnXmlFlowExecutionTests.java
index 75cbf1b..f894e65 100644
--- a/idp-oidc-rp-impl/src/test/java/net/shibboleth/idp/plugin/authn/test/flow/AbstractAuthnXmlFlowExecutionTests.java
+++ b/idp-oidc-rp-impl/src/test/java/net/shibboleth/idp/plugin/authn/test/flow/AbstractAuthnXmlFlowExecutionTests.java
@@ -17,9 +17,6 @@
 
 package net.shibboleth.idp.plugin.authn.test.flow;
 
-import java.io.InputStreamReader;
-import java.io.Reader;
-import java.nio.charset.StandardCharsets;
 import java.time.Duration;
 import java.util.Base64;
 import java.util.Collections;
@@ -55,7 +52,6 @@ import org.springframework.mock.env.MockPropertySource;
 import org.springframework.mock.web.MockHttpServletRequest;
 import org.springframework.mock.web.MockHttpServletResponse;
 import org.springframework.test.context.ContextConfiguration;
-import org.springframework.util.FileCopyUtils;
 import org.springframework.webflow.config.FlowDefinitionResource;
 import org.springframework.webflow.config.FlowDefinitionResourceFactory;
 import org.springframework.webflow.engine.Flow;
@@ -588,22 +584,7 @@ public abstract class AbstractAuthnXmlFlowExecutionTests extends CustomAbstractX
         return prc;
     }
     
-    /**
-     * Read a file into a string.
-     * 
-     * @param location the location of the file to read
-     * 
-     * @return the file as a string
-     */
-    protected String readJsonFromFile(@Nonnull final Resource location) {
-        try (Reader reader = new InputStreamReader(location.getInputStream(), StandardCharsets.UTF_8)) {
-            return FileCopyUtils.copyToString(reader);
-        } catch (final Exception ex) {
-            log.error("Error reading file",ex);
-            fail();
-            return null;
-        }
-    }
+
 
     
 
diff --git a/idp-oidc-rp-impl/src/test/resources/conf/credentials/test-provider-resolver-remote-jwkset-response.jwk b/idp-oidc-rp-impl/src/test/resources/conf/credentials/test-provider-resolver-remote-jwkset-response.jwk
new file mode 100644
index 0000000..5473bee
--- /dev/null
+++ b/idp-oidc-rp-impl/src/test/resources/conf/credentials/test-provider-resolver-remote-jwkset-response.jwk
@@ -0,0 +1,66 @@
+{
+"keys": [
+{
+"kty": "RSA",
+"e": "AQAB",
+"use": "sig",
+"kid": "7da9fea4-7a38-4398-aaef-8226b26776a2",
+"n": "kk-3jeBmUPbpMk0fEdIn-APAdNOoOckA0e-SiALLxy5dWfG-GyF51g31zuM_iNiSiMSsmG2ZAVi48iItFpd-JW9IIT40TC147I6aKrel0Rf39Mwp-1tCzME6VYEgOmgI9qDg2e4edt1cvjQfiw3IZlXakwgYQn2BuoknoCBVjETVLHrnsvEqXhPffzML9O5Ze_nBOX6-pCAzVsimr-ljoln2GQz-ID5fGzlflXJV78v7QzlyyAAQovYQMxiEBgecHu44S0Iu_esLEOOobQkZyHc-OgcwEazfJUEUhKEnevVTJFlQF3Odxp1I6W9zd-zLUceqIMKF5Xs10AfmkPhboQ"
+},
+{
+"kty": "RSA",
+"e": "AQAB",
+"use": "sig",
+"kid": "9ae4e77c-a0c7-4c52-982f-b8e5e6b62ab8",
+"n": "lBh4Ujl1k_H9CAfJe-SD-ngZnllWh5lShhv2FF_OlSlDEwr5wbf4WimeQhqLtfeT-dJXALpLSncaG_5y8pHHh0Pflnx_pZfCoOOc4Fba7wZgpHzfSQePwIDH8ygmzMLNzLaECa5m1LxnDD0oVHsABOab-_6_Uvuvam5xo2pKfJHoxkVsEDxQ2R0T_GfqC2bmCNJCdadeqw43yF_ILBRX-9sosA_7GPwyBWKAyiHX-DTUKwWrpR2bwCGE2Bxfgj3cDa97prSX8Vwpj_DEPOH8hbMAjO-N4EBcvcJZ0O0CD3X3IrquC__wqc9aOMEh2xbRxnTHdrNNG1KqzS8-L2yS0w"
+},
+{
+"kty": "EC",
+"use": "sig",
+"crv": "P-256",
+"kid": "7b1a7c28-df25-4d54-b111-11903db56d52",
+"x": "XRlwH72XaSlYjybpA6q4DTHsOphTuSWNPULNKwQ38wo",
+"y": "xWIoYZAyQxZM7RJCL-k14PdIHkCPo4m2tKRiCWyXU9w"
+},
+{
+"kty": "EC",
+"use": "sig",
+"crv": "P-256",
+"kid": "00cfe876-ed35-4052-8045-be1088c3212f",
+"x": "SwSHs_Df-Qxl83Mibu_lWzxn0mBn9hGts9gougQlrqs",
+"y": "kKQfhy4jDV_cxpC3iptQTFODkgENp-HC4XK7NIDqt5s"
+},
+{
+"kty": "EC",
+"use": "sig",
+"crv": "secp256k1",
+"kid": "4d1d9b37-3acc-46b9-9426-ee209db8541f",
+"x": "cZb41D8qgFxbpxnqOcp-kc78M8EdtSYqotje0IhWk_o",
+"y": "viJ95PgOZdYFPHRqdO4NOhRQgkejVDv8RmDprbLE31g"
+},
+{
+"kty": "OKP",
+"use": "sig",
+"crv": "Ed25519",
+"kid": "0c54869d-7d20-4faf-b607-3b040d1e1f27",
+"x": "gi3CalT0xmz8V52rgfdvYyM-rUwKnf8gUUUqB87Gycw"
+},
+{
+"kty": "RSA",
+"e": "AQAB",
+"use": "enc",
+"kid": "87ff206d-15f9-4b8c-ba88-a8c17014da13",
+"alg": "RSA-OAEP",
+"n": "uAVnVD3cMEbrAsDg1c3n6GfzR3sSg9C9pbjTw39_jgWk5YQCHPPOt4zYyZZL2JCnm9TFjnndCCW5ZPWHPJjumiNB2r-vC0CmI-T66JSRX3YYw0h2Odiusr_74FNe_mYyEuClFa4hwo-RMgrp8L1sbrAWcgGOc84rD6-fZXVrWFMkOb0jg6tqF1EwBSxZFG1cfvUmatNuBXs6njPHvvqhd7Bz6adK4YkpzCUbD-jSjpvAvU-Q4TZT_bXq4WRFOPqXv2NX4ch7ErjEm5tJEk7BIqOh7Byg0pWB4WAwsMcZKnHlp7JjtB2T1s_45_iqD2xipxpF-NxoHUlz67qHt7-W4Q"
+},
+{
+"kty": "EC",
+"use": "enc",
+"crv": "P-256",
+"kid": "c689ce91-8d82-45f2-b671-38ee38e7599f",
+"x": "redOUw802EuKJRoS8kQx6_RjuCypx0dcMBhv4IAALvQ",
+"y": "oaypduaS_wPLGCDQfJ0SKtQu0urJzhr4ZRn5wYMhiyk",
+"alg": "ECDH-ES"
+}
+]
+}
\ No newline at end of file
diff --git a/idp-oidc-rp-impl/src/test/resources/logback-test.xml b/idp-oidc-rp-impl/src/test/resources/logback-test.xml
index cabbb3c..2e54ae8 100644
--- a/idp-oidc-rp-impl/src/test/resources/logback-test.xml
+++ b/idp-oidc-rp-impl/src/test/resources/logback-test.xml
@@ -5,7 +5,8 @@
     <logger name="org.opensaml.xmlsec.impl" level="DEBUG"/>
     <logger name="net.shibboleth.idp.plugin.authn" level="TRACE"/>
     <logger name="org.springframework" level="INFO"/>
-
+    <logger name="org.opensaml.xmlsec.config.GlobalAlgorithmRegistryInitializer" level="DEBUG"/>
+    <logger name="org.opensaml.xmlsec.algorithm" level="DEBUG"/>
     <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
         <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
             <pattern>%level [%logger:%line] - %msg%n</pattern>
diff --git a/idp-oidc-rp-impl/src/test/resources/metadata/test-resolver-provider-encryption.json b/idp-oidc-rp-impl/src/test/resources/metadata/test-resolver-provider-encryption.json
new file mode 100644
index 0000000..02633d9
--- /dev/null
+++ b/idp-oidc-rp-impl/src/test/resources/metadata/test-resolver-provider-encryption.json
@@ -0,0 +1,89 @@
+{
+   "issuer":"https://localhost:9921",
+   "authorization_endpoint":"https://localhost:9921/o/oauth2/v2/auth",
+   "device_authorization_endpoint":"https://localhost:9921/device/code",
+   "token_endpoint":"https://localhost:9921/token",
+   "userinfo_endpoint":"https://localhost:9921/v1/userinfo",
+   "revocation_endpoint":"https://localhost:9921/revoke",
+   "jwks_uri":"https://localhost:9921/oauth2/v3/certs",
+   "claims_parameter_supported":true,
+   "request_parameter_supported":true,
+   "response_types_supported":[
+      "code",
+      "token",
+      "id_token",
+      "code token",
+      "code id_token",
+      "token id_token",
+      "code token id_token",
+      "none"
+   ],
+   "subject_types_supported":[
+      "public"
+   ],
+   "id_token_signing_alg_values_supported":[
+      "RS256"
+   ],
+   "request_object_signing_alg_values_supported":[
+      "HS256"
+   ],
+   "request_object_encryption_alg_values_supported":[
+      "RSA1_5",
+      "RSA-OAEP",
+      "RSA-OAEP-256",
+      "RSA-OAEP-384",
+      "RSA-OAEP-512",
+      "ECDH-ES",
+      "ECDH-ES+A128KW",
+      "ECDH-ES+A192KW",
+      "ECDH-ES+A256KW",
+      "A128KW",
+      "A192KW",
+      "A256KW",
+      "A128GCMKW",
+      "A192GCMKW",
+      "A256GCMKW",
+      "dir"
+   ],
+   "request_object_encryption_enc_values_supported":[
+      "A128CBC-HS256",
+      "A192CBC-HS384",
+      "A256CBC-HS512",
+      "A128GCM",
+      "A192GCM",
+      "A256GCM"
+   ],
+   "scopes_supported":[
+      "openid",
+      "email",
+      "profile"
+   ],
+   "token_endpoint_auth_methods_supported":[
+      "client_secret_post",
+      "client_secret_basic"
+   ],
+   "claims_supported":[
+      "aud",
+      "email",
+      "email_verified",
+      "exp",
+      "family_name",
+      "given_name",
+      "iat",
+      "iss",
+      "locale",
+      "name",
+      "picture",
+      "sub"
+   ],
+   "code_challenge_methods_supported":[
+      "plain",
+      "S256"
+   ],
+   "grant_types_supported":[
+      "authorization_code",
+      "refresh_token",
+      "urn:ietf:params:oauth:grant-type:device_code",
+      "urn:ietf:params:oauth:grant-type:jwt-bearer"
+   ]
+}
\ No newline at end of file

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


More information about the commits mailing list