[java-idp-oidc] branch main updated: JOIDC-38 Refactor fetching of remote JWK sets

Henri Mikkonen henri.mikkonen at iki.fi
Thu Mar 11 15:46:45 UTC 2021


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

hjmikkon pushed a commit to branch main
in repository java-idp-oidc.

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

The following commit(s) were added to refs/heads/main by this push:
       new  ad5e7707  JOIDC-38 Refactor fetching of remote JWK sets
ad5e7707 is described below

commit ad5e7707c985e6a30bf4cfb65ae9f2a245ae18e8
Author: Henri Mikkonen <henri.mikkonen at iki.fi>
AuthorDate: Thu Mar 11 17:45:39 2021 +0200

    JOIDC-38 Refactor fetching of remote JWK sets
    
    https://issues.shibboleth.net/jira/browse/JOIDC-38
    
    - The client information resolvers no longer fetches keys (via RemoteJwkSetCache)
    - OIDCClientInformationEncryptionParametersResolver and OIDCClientInformationSignatureValidationParametersResolver
    fetch them instead
    - Fetching interval is configurable via idp.oidc.jwksuri.fetchInterval property, defaults to 30 mins
---
 ...entInformationEncryptionParametersResolver.java |  45 +++++++++-
 ...ationSignatureValidationParametersResolver.java |  38 +++++++-
 .../META-INF/net.shibboleth.idp/postconfig.xml     |   6 ++
 .../idp/flows/oidc/authorize/authorize-beans.xml   |   5 +-
 .../idp/flows/oidc/token/token-beans.xml           |   4 +-
 .../idp/flows/oidc/userinfo/token-beans.xml        |   1 +
 .../oidc/op/conf/clientinfo-resolver-system.xml    |  12 +--
 .../idp/plugin/oidc/op/conf/oidc.properties        |   3 +
 ...nformationEncryptionParametersResolverTest.java |  81 ++++++++++++-----
 ...tionSignatureSigningParametersResolverTest.java |   4 +-
 ...nSignatureValidationParametersResolverTest.java | 100 +++++++++++++++------
 11 files changed, 234 insertions(+), 65 deletions(-)

diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/security/impl/OIDCClientInformationEncryptionParametersResolver.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/security/impl/OIDCClientInformationEncryptionParametersResolver.java
index a216a987..2dac699c 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/security/impl/OIDCClientInformationEncryptionParametersResolver.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/security/impl/OIDCClientInformationEncryptionParametersResolver.java
@@ -21,6 +21,8 @@ import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
 import java.security.interfaces.ECPrivateKey;
 import java.security.interfaces.RSAPrivateKey;
+import java.time.Duration;
+import java.time.Instant;
 import java.util.List;
 import java.util.function.Predicate;
 
@@ -30,8 +32,10 @@ import javax.crypto.SecretKey;
 import javax.crypto.spec.SecretKeySpec;
 
 import net.shibboleth.idp.plugin.oidc.op.criterion.ClientInformationCriterion;
+import net.shibboleth.oidc.jwk.RemoteJwkSetCache;
 import net.shibboleth.oidc.security.credential.BasicJWKCredential;
 import net.shibboleth.oidc.security.impl.OIDCDecryptionParameters;
+import net.shibboleth.utilities.java.support.annotation.constraint.Positive;
 import net.shibboleth.utilities.java.support.logic.Constraint;
 import net.shibboleth.utilities.java.support.resolver.CriteriaSet;
 import net.shibboleth.utilities.java.support.resolver.ResolverException;
@@ -93,6 +97,20 @@ public class OIDCClientInformationEncryptionParametersResolver extends BasicEncr
      * Whether to create parameters for request object decryption, id token encryption or userinfo response encryption.
      */
     private ParameterType target = ParameterType.IDTOKEN_ENCRYPTION;
+    
+    /** The cache for remote JWK key sets. */
+    private RemoteJwkSetCache remoteJwkSetCache;
+
+    /** The remote key refresh interval. Default value: 30 minutes. */
+    @Positive
+    private Duration keyFetchInterval = Duration.ofMinutes(30);
+    
+    /**
+     * Constructor.
+     */
+    public OIDCClientInformationEncryptionParametersResolver() {
+        super();
+    }
 
     /**
      * Whether to create parameters for request object decryption, id token encryption or userinfo response encryption.
@@ -104,6 +122,25 @@ public class OIDCClientInformationEncryptionParametersResolver extends BasicEncr
         target = value;
     }
 
+    /**
+     * Set the cache for remote JWK key sets.
+     * 
+     * @param jwkSetCache What to set.
+     */
+    public void setRemoteJwkSetCache(final RemoteJwkSetCache jwkSetCache) {
+        remoteJwkSetCache = Constraint.isNotNull(jwkSetCache, "The remote JWK set cache cannot be null");
+    }
+
+    /**
+     * Set the remote key refresh interval.
+     * 
+     * @param interval What to set.
+     */
+    public void setKeyFetchInterval(@Positive final Duration interval) {
+        Constraint.isFalse(interval == null || interval.isNegative(), "Remote key refresh must be greater than 0");
+        keyFetchInterval = interval;
+    }
+
     /** {@inheritDoc} */
     @Override
     @Nullable
@@ -236,7 +273,13 @@ public class OIDCClientInformationEncryptionParametersResolver extends BasicEncr
         }
         // For RSA & EC based encryption we pick one encryption key from client's registration data
         if (target != ParameterType.REQUEST_OBJECT_DECRYPTION) {
-            final JWKSet keySet = clientInformation.getOIDCMetadata().getJWKSet();
+            final JWKSet keySet;
+            if (clientInformation.getOIDCMetadata().getJWKSetURI() != null) {
+                keySet = remoteJwkSetCache.fetch(clientInformation.getOIDCMetadata().getJWKSetURI(),
+                        Instant.now().plus(keyFetchInterval));
+            } else {
+                keySet = clientInformation.getOIDCMetadata().getJWKSet();
+            }
             if (keySet == null) {
                 log.warn("No keyset available");
                 super.resolveAndPopulateCredentialsAndAlgorithms(params, criteria, whitelistBlacklistPredicate);
diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/security/impl/OIDCClientInformationSignatureValidationParametersResolver.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/security/impl/OIDCClientInformationSignatureValidationParametersResolver.java
index 346385c5..a7113a12 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/security/impl/OIDCClientInformationSignatureValidationParametersResolver.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/security/impl/OIDCClientInformationSignatureValidationParametersResolver.java
@@ -17,6 +17,8 @@
 
 package net.shibboleth.idp.plugin.oidc.op.security.impl;
 
+import java.time.Duration;
+import java.time.Instant;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
@@ -27,8 +29,10 @@ import javax.annotation.Nullable;
 import javax.crypto.spec.SecretKeySpec;
 
 import net.shibboleth.idp.plugin.oidc.op.criterion.ClientInformationCriterion;
+import net.shibboleth.oidc.jwk.RemoteJwkSetCache;
 import net.shibboleth.oidc.security.credential.BasicJWKCredential;
 import net.shibboleth.oidc.security.impl.OIDCSignatureValidationParameters;
+import net.shibboleth.utilities.java.support.annotation.constraint.Positive;
 import net.shibboleth.utilities.java.support.logic.Constraint;
 import net.shibboleth.utilities.java.support.resolver.CriteriaSet;
 import net.shibboleth.utilities.java.support.resolver.ResolverException;
@@ -83,6 +87,13 @@ public class OIDCClientInformationSignatureValidationParametersResolver
     }
 
     private ParameterType target = ParameterType.REQUEST_OBJECT_VALIDATION;
+    
+    /** The cache for remote JWK key sets. */
+    private RemoteJwkSetCache remoteJwkSetCache;
+
+    /** The remote key refresh interval. Default value: 30 minutes. */
+    @Positive
+    private Duration keyFetchInterval = Duration.ofMinutes(30);
 
     /**
      * Whether to create parameters for request object signature validation or token endpoint jwt validation.
@@ -94,6 +105,25 @@ public class OIDCClientInformationSignatureValidationParametersResolver
         target = value;
     }
 
+    /**
+     * Set the cache for remote JWK key sets.
+     * 
+     * @param jwkSetCache What to set.
+     */
+    public void setRemoteJwkSetCache(final RemoteJwkSetCache jwkSetCache) {
+        remoteJwkSetCache = Constraint.isNotNull(jwkSetCache, "The remote JWK set cache cannot be null");
+    }
+
+    /**
+     * Set the remote key refresh interval.
+     * 
+     * @param interval What to set.
+     */
+    public void setKeyFetchInterval(@Positive final Duration interval) {
+        Constraint.isFalse(interval == null || interval.isNegative(), "Remote key refresh must be greater than 0");
+        keyFetchInterval = interval;
+    }
+
     /** {@inheritDoc} */
     @Nullable
     public SignatureSigningParameters resolveSingle(@Nonnull final CriteriaSet criteria) throws ResolverException {
@@ -198,7 +228,13 @@ public class OIDCClientInformationSignatureValidationParametersResolver
             }
         }
         // For EC&RSA family signature validation we pick all suitable keys from client's registration data
-        final JWKSet keySet = clientInformation.getOIDCMetadata().getJWKSet();
+        final JWKSet keySet;
+        if (clientInformation.getOIDCMetadata().getJWKSetURI() != null) {
+            keySet = remoteJwkSetCache.fetch(clientInformation.getOIDCMetadata().getJWKSetURI(),
+                    Instant.now().plus(keyFetchInterval));
+        } else {
+            keySet = clientInformation.getOIDCMetadata().getJWKSet();
+        }
         if (keySet == null) {
             log.debug("No keyset available");
         } else {
diff --git a/idp-oidc-extension-impl/src/main/resources/META-INF/net.shibboleth.idp/postconfig.xml b/idp-oidc-extension-impl/src/main/resources/META-INF/net.shibboleth.idp/postconfig.xml
index 5a28b9b0..5cb34564 100644
--- a/idp-oidc-extension-impl/src/main/resources/META-INF/net.shibboleth.idp/postconfig.xml
+++ b/idp-oidc-extension-impl/src/main/resources/META-INF/net.shibboleth.idp/postconfig.xml
@@ -148,5 +148,11 @@
             </list>
         </constructor-arg>
     </bean>
+
+    <bean id="shibboleth.oidc.RemoteJwkSetCache"
+        class="net.shibboleth.oidc.jwk.RemoteJwkSetCache"
+        p:storage-ref="#{'%{idp.oidc.jwk.StorageService:shibboleth.StorageService}'.trim()}"
+        p:httpClient="#{getObject('shibboleth.oidc.NonBrowser.HttpClient') ?: getObject('shibboleth.InternalHttpClient')}"
+        p:httpClientSecurityParameters="#{getObject('shibboleth.oidc.NonBrowser.HttpClientSecurityParameters')}" />
     
 </beans>
diff --git a/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidc/authorize/authorize-beans.xml b/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidc/authorize/authorize-beans.xml
index 4560c92a..47dedfa8 100644
--- a/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidc/authorize/authorize-beans.xml
+++ b/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidc/authorize/authorize-beans.xml
@@ -61,6 +61,7 @@
 
     <bean id="shibboleth.oidc.EncryptionParametersResolverForRequestObjectDecryption"
         class="net.shibboleth.idp.plugin.oidc.op.security.impl.OIDCClientInformationEncryptionParametersResolver"
+        p:remoteJwkSetCache-ref="shibboleth.oidc.RemoteJwkSetCache" p:keyFetchInterval="%{idp.oidc.jwksuri.fetchInterval:PT30M}"
         p:parameterType="#{T(net.shibboleth.idp.plugin.oidc.op.security.impl.OIDCClientInformationEncryptionParametersResolver.ParameterType).REQUEST_OBJECT_DECRYPTION}" />
 
     <bean id="shibboleth.oidc.DecryptionConfigurationLookup"
@@ -89,6 +90,7 @@
 
     <bean id="shibboleth.oidc.RequestObjectSignatureValidationParametersResolver"
         class="net.shibboleth.idp.plugin.oidc.op.security.impl.OIDCClientInformationSignatureValidationParametersResolver"
+        p:remoteJwkSetCache-ref="shibboleth.oidc.RemoteJwkSetCache" p:keyFetchInterval="%{idp.oidc.jwksuri.fetchInterval:PT30M}"
         p:parameterType="#{T(net.shibboleth.idp.plugin.oidc.op.security.impl.OIDCClientInformationSignatureValidationParametersResolver.ParameterType).REQUEST_OBJECT_VALIDATION}" />
 
     <bean id="SetRequestObjectToResponseContext"
@@ -145,7 +147,8 @@
     </bean>
 
     <bean id="shibboleth.oidc.EncryptionParametersResolver"
-        class="net.shibboleth.idp.plugin.oidc.op.security.impl.OIDCClientInformationEncryptionParametersResolver" />
+        class="net.shibboleth.idp.plugin.oidc.op.security.impl.OIDCClientInformationEncryptionParametersResolver"
+        p:remoteJwkSetCache-ref="shibboleth.oidc.RemoteJwkSetCache" p:keyFetchInterval="%{idp.oidc.jwksuri.fetchInterval:PT30M}" />
 
     <bean id="PopulateClientStorageLoadContext"
         class="org.opensaml.storage.impl.client.PopulateClientStorageLoadContext" scope="prototype"
diff --git a/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidc/token/token-beans.xml b/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidc/token/token-beans.xml
index 95daf251..095b56db 100644
--- a/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidc/token/token-beans.xml
+++ b/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidc/token/token-beans.xml
@@ -117,7 +117,8 @@
         p:encryptionParametersResolver-ref="shibboleth.oidc.EncryptionParametersResolver" />
 
     <bean id="shibboleth.oidc.EncryptionParametersResolver"
-        class="net.shibboleth.idp.plugin.oidc.op.security.impl.OIDCClientInformationEncryptionParametersResolver" />
+        class="net.shibboleth.idp.plugin.oidc.op.security.impl.OIDCClientInformationEncryptionParametersResolver"
+        p:remoteJwkSetCache-ref="shibboleth.oidc.RemoteJwkSetCache" p:keyFetchInterval="%{idp.oidc.jwksuri.fetchInterval:PT30M}" />
 
     <bean id="shibboleth.TokenRequestScopeLookupStrategy"
         class="net.shibboleth.idp.plugin.oidc.op.profile.context.navigate.TokenRequestScopeLookupFunction"
@@ -235,6 +236,7 @@
 
     <bean id="shibboleth.oidc.TokenEndpointJwtSignatureValidationParametersResolver"
         class="net.shibboleth.idp.plugin.oidc.op.security.impl.OIDCClientInformationSignatureValidationParametersResolver"
+        p:remoteJwkSetCache-ref="shibboleth.oidc.RemoteJwkSetCache" p:keyFetchInterval="%{idp.oidc.jwksuri.fetchInterval:PT30M}"
         p:parameterType="#{T(net.shibboleth.idp.plugin.oidc.op.security.impl.OIDCClientInformationSignatureValidationParametersResolver.ParameterType).TOKEN_ENDPOINT_JWT_VALIDATION}" />
 
 </beans>
diff --git a/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidc/userinfo/token-beans.xml b/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidc/userinfo/token-beans.xml
index 8dbfcf6f..004c7265 100644
--- a/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidc/userinfo/token-beans.xml
+++ b/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/oidc/userinfo/token-beans.xml
@@ -85,6 +85,7 @@
 
     <bean id="shibboleth.oidc.EncryptionParametersResolver"
         class="net.shibboleth.idp.plugin.oidc.op.security.impl.OIDCClientInformationEncryptionParametersResolver"
+        p:remoteJwkSetCache-ref="shibboleth.oidc.RemoteJwkSetCache" p:keyFetchInterval="%{idp.oidc.jwksuri.fetchInterval:PT30M}"
         p:parameterType="#{T(net.shibboleth.idp.plugin.oidc.op.security.impl.OIDCClientInformationEncryptionParametersResolver.ParameterType).USERINFO_ENCRYPTION}" />
 
     <bean id="shibboleth.TokenRequestRequestedClaimsLookupFunction"
diff --git a/idp-oidc-extension-impl/src/main/resources/net/shibboleth/idp/plugin/oidc/op/conf/clientinfo-resolver-system.xml b/idp-oidc-extension-impl/src/main/resources/net/shibboleth/idp/plugin/oidc/op/conf/clientinfo-resolver-system.xml
index 38d0e194..f035db57 100644
--- a/idp-oidc-extension-impl/src/main/resources/net/shibboleth/idp/plugin/oidc/op/conf/clientinfo-resolver-system.xml
+++ b/idp-oidc-extension-impl/src/main/resources/net/shibboleth/idp/plugin/oidc/op/conf/clientinfo-resolver-system.xml
@@ -18,24 +18,16 @@
         p:embeddedResolver-ref="shibboleth.oidc.ChainingClientInformationResolver">
     </bean>
 
-    <bean id="shibboleth.oidc.RemoteJwkSetCache"
-        class="net.shibboleth.oidc.jwk.RemoteJwkSetCache"
-        p:storage-ref="#{'%{idp.oidc.jwk.StorageService:shibboleth.StorageService}'.trim()}"
-        p:httpClient="#{getObject('shibboleth.oidc.NonBrowser.HttpClient') ?: getObject('shibboleth.InternalHttpClient')}"
-        p:httpClientSecurityParameters="#{getObject('shibboleth.oidc.NonBrowser.HttpClientSecurityParameters')}" />
-
     <bean id="shibboleth.oidc.ChainingClientInformationResolver"
         class="net.shibboleth.oidc.metadata.impl.ChainingClientInformationResolver"
         p:id="InternalEmbeddedChainResolver" 
         p:resolvers="#{getObject('shibboleth.oidc.ClientInformationResolvers')}"/>
 
     <bean id="shibboleth.oidc.FilesystemClientInformationResolver" abstract="true"
-        class="net.shibboleth.oidc.metadata.impl.FilesystemClientInformationResolver" 
-        p:remoteJwkSetCache-ref="shibboleth.oidc.RemoteJwkSetCache" />
+        class="net.shibboleth.oidc.metadata.impl.FilesystemClientInformationResolver"/>
 
     <bean id="shibboleth.oidc.StorageClientInformationResolver" abstract="true"
-        class="net.shibboleth.oidc.metadata.impl.StorageServiceClientInformationResolver"
-        p:remoteJwkSetCache-ref="shibboleth.oidc.RemoteJwkSetCache"/>
+        class="net.shibboleth.oidc.metadata.impl.StorageServiceClientInformationResolver"/>
 
     <!-- Wildcard import hook for plugins. -->
     <import resource="classpath*:/META-INF/net/shibboleth/idp/plugin/oidc/op/service/clientinfo/postconfig.xml" />
diff --git a/idp-oidc-extension-impl/src/main/resources/net/shibboleth/idp/plugin/oidc/op/conf/oidc.properties b/idp-oidc-extension-impl/src/main/resources/net/shibboleth/idp/plugin/oidc/op/conf/oidc.properties
index cbdd8f32..a7dc49dd 100644
--- a/idp-oidc-extension-impl/src/main/resources/net/shibboleth/idp/plugin/oidc/op/conf/oidc.properties
+++ b/idp-oidc-extension-impl/src/main/resources/net/shibboleth/idp/plugin/oidc/op/conf/oidc.properties
@@ -72,3 +72,6 @@ idp.oidc.subject.salt = this_too_should_be_ch4ng3d
 
 # Bean to determine whether SAML metadata should be exploited for trusted OIDC RP resolution
 #idp.oidc.metadata.saml = shibboleth.Conditions.TRUE
+
+# Upgrade interval to the remote JWKs
+#idp.oidc.jwksuri.fetchInterval = PT30M
diff --git a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/security/impl/OIDCClientInformationEncryptionParametersResolverTest.java b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/security/impl/OIDCClientInformationEncryptionParametersResolverTest.java
index 744fbf21..5058b3dc 100644
--- a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/security/impl/OIDCClientInformationEncryptionParametersResolverTest.java
+++ b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/security/impl/OIDCClientInformationEncryptionParametersResolverTest.java
@@ -17,12 +17,15 @@
 
 package net.shibboleth.idp.plugin.oidc.op.security.impl;
 
+import java.net.URI;
+import java.text.ParseException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Date;
 import java.util.List;
 
 import org.mockito.Mockito;
+import org.opensaml.core.testing.OpenSAMLInitBaseTestCase;
 import org.opensaml.security.credential.Credential;
 import org.opensaml.xmlsec.EncryptionConfiguration;
 import org.opensaml.xmlsec.EncryptionParameters;
@@ -34,6 +37,7 @@ import org.testng.annotations.Test;
 import com.nimbusds.jose.EncryptionMethod;
 import com.nimbusds.jose.JWEAlgorithm;
 import com.nimbusds.jose.jwk.JWKSet;
+import com.nimbusds.jose.jwk.RSAKey;
 import com.nimbusds.oauth2.sdk.auth.Secret;
 import com.nimbusds.oauth2.sdk.id.ClientID;
 import com.nimbusds.openid.connect.sdk.rp.OIDCClientInformation;
@@ -41,25 +45,39 @@ import com.nimbusds.openid.connect.sdk.rp.OIDCClientMetadata;
 
 import net.shibboleth.idp.plugin.oidc.op.criterion.ClientInformationCriterion;
 import net.shibboleth.idp.plugin.oidc.op.profile.spring.factory.BasicJWKCredentialFactoryBean;
-import net.shibboleth.idp.plugin.oidc.op.security.impl.OIDCClientInformationEncryptionParametersResolver;
 import net.shibboleth.idp.plugin.oidc.op.security.impl.OIDCClientInformationEncryptionParametersResolver.ParameterType;
+import net.shibboleth.oidc.jwk.RemoteJwkSetCache;
 import net.shibboleth.oidc.security.impl.OIDCDecryptionParameters;
 import net.shibboleth.utilities.java.support.resolver.CriteriaSet;
-import net.shibboleth.utilities.java.support.resolver.ResolverException;
 
 /**
  * Tests for {@link OIDCClientInformationEncryptionParametersResolver}.
  */
-public class OIDCClientInformationEncryptionParametersResolverTest {
+public class OIDCClientInformationEncryptionParametersResolverTest extends OpenSAMLInitBaseTestCase {
 
     private OIDCClientInformationEncryptionParametersResolver resolver;
 
     private CriteriaSet criteria;
 
     private OIDCClientMetadata metaData;
-
+    
+    private JWKSet jwkSet;
+    
     @BeforeMethod
-    protected void setUp() throws Exception {
+    protected void setUp() throws ParseException {
+        jwkSet = JWKSet.parse("{\n" + "  \"keys\": [\n" + "    {\n" + "      \"kty\": \"EC\",\n"
+                + "      \"d\": \"MeEUizlBfHEfftMzSUYmtltJr87NUn2WZqxKDVPMlxM\",\n" + "      \"crv\": \"P-256\",\n"
+                + "      \"x\": \"psUf_1U4lV0u2zSRjVepDMyLV4JeLoWNcz3F3C91z4Y\",\n"
+                + "      \"y\": \"z29JaoRl_1wgGPEKq7-5qvts9vbEwA7hk5Vg01h8ESc\"\n" + "    },\n" + "    {\n"
+                + "      \"kty\": \"RSA\",\n"
+                + "      \"kid\": \"testRsaKey\",\n"
+                + "      \"d\": \"RBl-MjdugxTrjVbbWSeArOV7HUiZPX5LWmyB9p3P1OLSSYjK9A42KYPsdcLpa78Den5_fcpLv-1pm8161ATE9Y_O2aIkeg0_IRlM-FLo-KHvtGkEuHcbERPGhrvmsyMsqkVGADhEwvcGsWZ9PZSHo8OK8EsHZWmE2kHN_rG_8n9-ymAvdsHHv5WhyppHtScLWR1UoIQVbnmcw0cauBy-6SYL2pnweWMeI5UDB6eYyeUyA8BuV-_40K0XqJgJ--6zkNdsSrAMbOejfSyAgK7ezCCP-gmS2P3tBLqwJKjCcoDGFihHj6qLUFNWDY5flp3vA02Z8DQKroeAtIN0_PSBIQ\",\n"
+                + "      \"e\": \"AQAB\",\n"
+                + "      \"n\": \"xC18p5gfcin62WKas_DlmwUE0ySwmgW51gDQhqucBBSyHMvzRXzRY1cYkox4WCLreC3X8YbNgAv9fjkagX35aNyafnJxEd3Cipf6-h_tZ8Ky5mtdKrxpJdGW1mom7Ha8nMAFGmElDtQny2U8pzDUAUvOcOjiI-JRd6WH3wyQtpCtG6YYxhS9SvnvDaNlYN_afPgFdTHt5yn-q854bjF6uG-uZt3J7jf7P6dvqVizDVO9xtCHrjeet4v62yscMZXYi110aMJdtA4nxKGUi9RWCnBoLVRMBei5ZqmsLCozT5KpfVNkjVzZU3vYBKdGw49pIgRqQP-Jx8Sg7JFaaXMBsQ\"\n"
+                + "    }" + "  ]\n" + "}");
+    }
+
+    protected void initTest(RemoteJwkSetCache remoteJwkSetCache) throws Exception {
         resolver = new OIDCClientInformationEncryptionParametersResolver();
         // Encryption configuration
         List<EncryptionConfiguration> configs = new ArrayList<EncryptionConfiguration>();
@@ -83,31 +101,52 @@ public class OIDCClientInformationEncryptionParametersResolverTest {
         metaData.setUserInfoJWEEnc(EncryptionMethod.A128GCM);
         metaData.setRequestObjectJWEAlg(JWEAlgorithm.RSA_OAEP_256);
         metaData.setRequestObjectJWEEnc(EncryptionMethod.A192GCM);
-        JWKSet jwkSet = JWKSet.parse("{\n" + "  \"keys\": [\n" + "    {\n" + "      \"kty\": \"EC\",\n"
-                + "      \"d\": \"MeEUizlBfHEfftMzSUYmtltJr87NUn2WZqxKDVPMlxM\",\n" + "      \"crv\": \"P-256\",\n"
-                + "      \"x\": \"psUf_1U4lV0u2zSRjVepDMyLV4JeLoWNcz3F3C91z4Y\",\n"
-                + "      \"y\": \"z29JaoRl_1wgGPEKq7-5qvts9vbEwA7hk5Vg01h8ESc\"\n" + "    },\n" + "    {\n"
-                + "      \"kty\": \"RSA\",\n"
-                + "      \"d\": \"RBl-MjdugxTrjVbbWSeArOV7HUiZPX5LWmyB9p3P1OLSSYjK9A42KYPsdcLpa78Den5_fcpLv-1pm8161ATE9Y_O2aIkeg0_IRlM-FLo-KHvtGkEuHcbERPGhrvmsyMsqkVGADhEwvcGsWZ9PZSHo8OK8EsHZWmE2kHN_rG_8n9-ymAvdsHHv5WhyppHtScLWR1UoIQVbnmcw0cauBy-6SYL2pnweWMeI5UDB6eYyeUyA8BuV-_40K0XqJgJ--6zkNdsSrAMbOejfSyAgK7ezCCP-gmS2P3tBLqwJKjCcoDGFihHj6qLUFNWDY5flp3vA02Z8DQKroeAtIN0_PSBIQ\",\n"
-                + "      \"e\": \"AQAB\",\n"
-                + "      \"n\": \"xC18p5gfcin62WKas_DlmwUE0ySwmgW51gDQhqucBBSyHMvzRXzRY1cYkox4WCLreC3X8YbNgAv9fjkagX35aNyafnJxEd3Cipf6-h_tZ8Ky5mtdKrxpJdGW1mom7Ha8nMAFGmElDtQny2U8pzDUAUvOcOjiI-JRd6WH3wyQtpCtG6YYxhS9SvnvDaNlYN_afPgFdTHt5yn-q854bjF6uG-uZt3J7jf7P6dvqVizDVO9xtCHrjeet4v62yscMZXYi110aMJdtA4nxKGUi9RWCnBoLVRMBei5ZqmsLCozT5KpfVNkjVzZU3vYBKdGw49pIgRqQP-Jx8Sg7JFaaXMBsQ\"\n"
-                + "    }" + "  ]\n" + "}");
-        metaData.setJWKSet(jwkSet);
+        if (remoteJwkSetCache != null) {
+            resolver.setRemoteJwkSetCache(remoteJwkSetCache);
+            metaData.setJWKSetURI(new URI("https://rp.example.org/jwks"));
+        } else {
+            metaData.setJWKSet(jwkSet);
+        }
         OIDCClientInformation clientInformation =
                 new OIDCClientInformation(new ClientID(), new Date(), metaData, new Secret("abcdefgh"));
         criteria.add(new ClientInformationCriterion(clientInformation));
     }
 
     @Test
-    public void testIdTokenParameters() throws ResolverException {
+    public void testIdTokenParameters() throws Exception {
+        initTest(null);
         EncryptionParameters params = resolver.resolveSingle(criteria);
         Assert.assertEquals("RSA-OAEP-256", params.getKeyTransportEncryptionAlgorithm());
         Assert.assertEquals("A192CBC-HS384", params.getDataEncryptionAlgorithm());
-        Assert.assertNotNull(params.getKeyTransportEncryptionCredential().getPublicKey());
+        Assert.assertEquals(((RSAKey) jwkSet.getKeyByKeyId("testRsaKey")).toPublicKey(),
+                params.getKeyTransportEncryptionCredential().getPublicKey());
+    }
+
+    @Test
+    public void testIdTokenParametersRemoteKey() throws Exception {
+        RemoteJwkSetCache remoteJwkSetCache = Mockito.mock(RemoteJwkSetCache.class);
+        Mockito.when(remoteJwkSetCache.fetch(Mockito.any(), Mockito.any())).thenReturn(jwkSet);
+        initTest(remoteJwkSetCache);
+        EncryptionParameters params = resolver.resolveSingle(criteria);
+        Assert.assertEquals("RSA-OAEP-256", params.getKeyTransportEncryptionAlgorithm());
+        Assert.assertEquals("A192CBC-HS384", params.getDataEncryptionAlgorithm());
+        Assert.assertEquals(((RSAKey) jwkSet.getKeyByKeyId("testRsaKey")).toPublicKey(),
+                params.getKeyTransportEncryptionCredential().getPublicKey());
+    }
+
+    @Test
+    public void testIdTokenParametersNoKey() throws Exception {
+        RemoteJwkSetCache remoteJwkSetCache = Mockito.mock(RemoteJwkSetCache.class);
+        Mockito.when(remoteJwkSetCache.fetch(Mockito.any(), Mockito.any())).thenReturn(null);
+        initTest(remoteJwkSetCache);
+        EncryptionParameters params = resolver.resolveSingle(criteria);
+        Assert.assertNotEquals(((RSAKey) jwkSet.getKeyByKeyId("testRsaKey")).toPublicKey(),
+                params.getKeyTransportEncryptionCredential().getPublicKey());
     }
 
     @Test
-    public void testIdTokenParametersDefaultEnc() throws ResolverException {
+    public void testIdTokenParametersDefaultEnc() throws Exception {
+        initTest(null);
         metaData.setIDTokenJWEEnc(null);
         EncryptionParameters params = resolver.resolveSingle(criteria);
         Assert.assertEquals("RSA-OAEP-256", params.getKeyTransportEncryptionAlgorithm());
@@ -116,7 +155,8 @@ public class OIDCClientInformationEncryptionParametersResolverTest {
     }
 
     @Test
-    public void testUserInfoParameters() throws ResolverException {
+    public void testUserInfoParameters() throws Exception {
+        initTest(null);
         resolver.setParameterType(ParameterType.USERINFO_ENCRYPTION);
         EncryptionParameters params = resolver.resolveSingle(criteria);
         Assert.assertEquals("A128GCMKW", params.getKeyTransportEncryptionAlgorithm());
@@ -125,7 +165,8 @@ public class OIDCClientInformationEncryptionParametersResolverTest {
     }
 
     @Test
-    public void testRequesrObjectParameters() throws ResolverException {
+    public void testRequesrObjectParameters() throws Exception {
+        initTest(null);
         resolver.setParameterType(ParameterType.REQUEST_OBJECT_DECRYPTION);
         EncryptionParameters params = resolver.resolveSingle(criteria);
         Assert.assertEquals("RSA-OAEP-256", params.getKeyTransportEncryptionAlgorithm());
diff --git a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/security/impl/OIDCClientInformationSignatureSigningParametersResolverTest.java b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/security/impl/OIDCClientInformationSignatureSigningParametersResolverTest.java
index 262eec96..523e47db 100644
--- a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/security/impl/OIDCClientInformationSignatureSigningParametersResolverTest.java
+++ b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/security/impl/OIDCClientInformationSignatureSigningParametersResolverTest.java
@@ -25,6 +25,7 @@ import java.util.Date;
 import java.util.List;
 
 import org.mockito.Mockito;
+import org.opensaml.core.testing.OpenSAMLInitBaseTestCase;
 import org.opensaml.security.credential.Credential;
 import org.opensaml.xmlsec.SignatureSigningConfiguration;
 import org.opensaml.xmlsec.SignatureSigningParameters;
@@ -43,7 +44,6 @@ import com.nimbusds.openid.connect.sdk.rp.OIDCClientMetadata;
 
 import net.shibboleth.idp.plugin.oidc.op.criterion.ClientInformationCriterion;
 import net.shibboleth.idp.plugin.oidc.op.profile.spring.factory.BasicJWKCredentialFactoryBean;
-import net.shibboleth.idp.plugin.oidc.op.security.impl.OIDCClientInformationSignatureSigningParametersResolver;
 import net.shibboleth.idp.plugin.oidc.op.security.impl.OIDCClientInformationSignatureSigningParametersResolver.ParameterType;
 import net.shibboleth.oidc.security.impl.OIDCSignatureValidationParameters;
 import net.shibboleth.utilities.java.support.resolver.CriteriaSet;
@@ -52,7 +52,7 @@ import net.shibboleth.utilities.java.support.resolver.ResolverException;
 /**
  * Tests for {@link OIDCClientInformationSignatureSigningParametersResolver}.
  */
-public class OIDCClientInformationSignatureSigningParametersResolverTest {
+public class OIDCClientInformationSignatureSigningParametersResolverTest extends OpenSAMLInitBaseTestCase {
 
     private OIDCClientInformationSignatureSigningParametersResolver resolver;
 
diff --git a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/security/impl/OIDCClientInformationSignatureValidationParametersResolverTest.java b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/security/impl/OIDCClientInformationSignatureValidationParametersResolverTest.java
index 8e148065..4045ec34 100644
--- a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/security/impl/OIDCClientInformationSignatureValidationParametersResolverTest.java
+++ b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/security/impl/OIDCClientInformationSignatureValidationParametersResolverTest.java
@@ -17,12 +17,15 @@
 
 package net.shibboleth.idp.plugin.oidc.op.security.impl;
 
+import java.net.URI;
+import java.text.ParseException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Date;
 import java.util.List;
 
 import org.mockito.Mockito;
+import org.opensaml.core.testing.OpenSAMLInitBaseTestCase;
 import org.opensaml.xmlsec.SignatureSigningConfiguration;
 import org.opensaml.xmlsec.criterion.SignatureSigningConfigurationCriterion;
 import org.testng.Assert;
@@ -38,8 +41,8 @@ import com.nimbusds.openid.connect.sdk.rp.OIDCClientInformation;
 import com.nimbusds.openid.connect.sdk.rp.OIDCClientMetadata;
 
 import net.shibboleth.idp.plugin.oidc.op.criterion.ClientInformationCriterion;
-import net.shibboleth.idp.plugin.oidc.op.security.impl.OIDCClientInformationSignatureValidationParametersResolver;
 import net.shibboleth.idp.plugin.oidc.op.security.impl.OIDCClientInformationSignatureValidationParametersResolver.ParameterType;
+import net.shibboleth.oidc.jwk.RemoteJwkSetCache;
 import net.shibboleth.oidc.security.impl.OIDCSignatureValidationParameters;
 import net.shibboleth.utilities.java.support.resolver.CriteriaSet;
 import net.shibboleth.utilities.java.support.resolver.ResolverException;
@@ -47,7 +50,7 @@ import net.shibboleth.utilities.java.support.resolver.ResolverException;
 /**
  * Tests for {@link OIDCClientInformationSignatureValidationParametersResolver}.
  */
-public class OIDCClientInformationSignatureValidationParametersResolverTest {
+public class OIDCClientInformationSignatureValidationParametersResolverTest extends OpenSAMLInitBaseTestCase {
 
     private OIDCClientInformationSignatureValidationParametersResolver resolver;
 
@@ -55,20 +58,11 @@ public class OIDCClientInformationSignatureValidationParametersResolverTest {
 
     private OIDCClientMetadata metaData;
 
+    private JWKSet jwkSet;
+    
     @BeforeMethod
-    protected void setUp() throws Exception {
-        resolver = new OIDCClientInformationSignatureValidationParametersResolver();
-        // Signing configuration
-        List<SignatureSigningConfiguration> configs = new ArrayList<SignatureSigningConfiguration>();
-        SignatureSigningConfiguration signConfig = Mockito.mock(SignatureSigningConfiguration.class);
-        Mockito.when(signConfig.getSignatureAlgorithms())
-                .thenReturn(Arrays.asList("RS256", "HS256", "HS384", "HS512", "ES256", "ES384", "ES512"));
-        configs.add(signConfig);
-        criteria = new CriteriaSet(new SignatureSigningConfigurationCriterion(configs));
-        metaData = new OIDCClientMetadata();
-        metaData.setRequestObjectJWSAlg(JWSAlgorithm.ES256);
-        metaData.setTokenEndpointAuthJWSAlg(JWSAlgorithm.ES256);
-        JWKSet jwkSet = JWKSet.parse("{\n" + "   \"keys\":[\n" + "      {\n" + "         \"kty\":\"RSA\",\n"
+    protected void setUp() throws ParseException {
+        jwkSet = JWKSet.parse("{\n" + "   \"keys\":[\n" + "      {\n" + "         \"kty\":\"RSA\",\n"
                 + "         \"e\":\"AQAB\",\n" + "         \"use\":\"enc\",\n"
                 + "         \"kid\":\"testkeyRSAEncryption\",\n"
                 + "         \"n\":\"47mkdLGrenv7QFkAWv1JryydVjq8HsEVCKz-qRttVe2II1-lQc-4sObf-9X0LtAwdtK0g1_EpRzZNuGaK2nFISr9uZQQ5evNHETgUKE2oKJs3r0wnfgvEZVHV6wXg4B7NRmDBgphExIYndBt__L-tC9_S_isaJOXQ_PAx17621pmxdyg8WEnJx9Azc23vH-Cii0ttMxDLNqUTu-tdgtZ8eo0IX7VPBWAnXVi0bRKHJuuvzJ4B8QqwsZsj8hGrwqNkRMoJVEiz-5M6ACLo-rgGNjtCBJRaezolrHSCc-r-hZbAaBKq0dOPRNPcMtRm8TUdmuRKBY7rXaFi7zGV7XDdw\"\n"
@@ -91,79 +85,127 @@ public class OIDCClientInformationSignatureValidationParametersResolverTest {
                 + "         \"kid\":\"testkeyES512-2\",\n"
                 + "         \"x\":\"AQL7ZCkzcAyuUdaqYiCSAf2u2MR_l4rqSppQ8lvEEjmjy7ETiPB77BqeH7glJ6xtkK1YhmHxKDKz0E0zdmqWWVYp\",\n"
                 + "         \"y\":\"AXI7UFlH-Zy2jEf1XoY3NHblkJDsOK4kiv82fRrKtHAoKM_ud25XNzT3lrfbJ--zZlmWUB7fV2jHR0pbmjOOrEF_\"\n"
-                + "      }\n" + "   ]\n" + "}");
-        metaData.setJWKSet(jwkSet);
+                + "      }\n" + "   ]\n" + "}");        
+    }
+
+    protected void initTest(RemoteJwkSetCache remoteJwkSetCache) throws Exception {
+        resolver = new OIDCClientInformationSignatureValidationParametersResolver();
+        // Signing configuration
+        List<SignatureSigningConfiguration> configs = new ArrayList<SignatureSigningConfiguration>();
+        SignatureSigningConfiguration signConfig = Mockito.mock(SignatureSigningConfiguration.class);
+        Mockito.when(signConfig.getSignatureAlgorithms())
+                .thenReturn(Arrays.asList("RS256", "HS256", "HS384", "HS512", "ES256", "ES384", "ES512"));
+        configs.add(signConfig);
+        criteria = new CriteriaSet(new SignatureSigningConfigurationCriterion(configs));
+        metaData = new OIDCClientMetadata();
+        metaData.setRequestObjectJWSAlg(JWSAlgorithm.ES256);
+        metaData.setTokenEndpointAuthJWSAlg(JWSAlgorithm.ES256);
+        if (remoteJwkSetCache != null) {
+            resolver.setRemoteJwkSetCache(remoteJwkSetCache);
+            metaData.setJWKSetURI(new URI("https://rp.example.org/jwks"));
+        } else {
+            metaData.setJWKSet(jwkSet);
+        }
         OIDCClientInformation clientInformation =
                 new OIDCClientInformation(new ClientID(), new Date(), metaData, new Secret("abcdefgh"));
         criteria.add(new ClientInformationCriterion(clientInformation));
     }
 
     @Test
-    public void testRequestObjectParameters() throws ResolverException {
+    public void testRequestObjectParameters() throws Exception {
+        initTest(null);
         testSigningValidationES256(ParameterType.REQUEST_OBJECT_VALIDATION);
     }
 
     @Test
-    public void testRequestObjectParametersES384() throws ResolverException {
+    public void testRequestObjectParametersRemoteKeys() throws Exception {
+        RemoteJwkSetCache remoteJwkSetCache = Mockito.mock(RemoteJwkSetCache.class);
+        Mockito.when(remoteJwkSetCache.fetch(Mockito.any(), Mockito.any())).thenReturn(jwkSet);
+        initTest(remoteJwkSetCache);
+        testSigningValidationES256(ParameterType.REQUEST_OBJECT_VALIDATION);
+    }
+
+    @Test
+    public void testRequestObjectParametersNoKeys() throws Exception {
+        RemoteJwkSetCache remoteJwkSetCache = Mockito.mock(RemoteJwkSetCache.class);
+        Mockito.when(remoteJwkSetCache.fetch(Mockito.any(), Mockito.any())).thenReturn(null);
+        initTest(remoteJwkSetCache);
+        resolver.setParameterType(ParameterType.REQUEST_OBJECT_VALIDATION);
+        Assert.assertNull(resolver.resolveSingle(criteria));
+    }
+
+    @Test
+    public void testRequestObjectParametersES384() throws Exception {
+        initTest(null);
         metaData.setRequestObjectJWSAlg(JWSAlgorithm.ES384);
         testSigningValidationES384(ParameterType.REQUEST_OBJECT_VALIDATION);
     }
 
     @Test
-    public void testRequestObjectParametersES512() throws ResolverException {
+    public void testRequestObjectParametersES512() throws Exception {
+        initTest(null);
         metaData.setRequestObjectJWSAlg(JWSAlgorithm.ES512);
         testSigningValidationES512(ParameterType.REQUEST_OBJECT_VALIDATION);
     }
 
     @Test
-    public void testRequestObjectParametersHS256() throws ResolverException {
+    public void testRequestObjectParametersHS256() throws Exception {
+        initTest(null);
         metaData.setRequestObjectJWSAlg(JWSAlgorithm.HS256);
         testSigningValidationHS256(ParameterType.REQUEST_OBJECT_VALIDATION);
     }
 
     @Test
-    public void testRequestObjectParametersHS384() throws ResolverException {
+    public void testRequestObjectParametersHS384() throws Exception {
+        initTest(null);
         metaData.setRequestObjectJWSAlg(JWSAlgorithm.HS384);
         testSigningValidationHS384(ParameterType.REQUEST_OBJECT_VALIDATION);
     }
 
     @Test
-    public void testRequestObjectParametersHS512() throws ResolverException {
+    public void testRequestObjectParametersHS512() throws Exception {
+        initTest(null);
         metaData.setRequestObjectJWSAlg(JWSAlgorithm.HS512);
         testSigningValidationHS512(ParameterType.REQUEST_OBJECT_VALIDATION);
     }
 
     @Test
-    public void testTokenEndpointJwtParameters() throws ResolverException {
+    public void testTokenEndpointJwtParameters() throws Exception {
+        initTest(null);
         testSigningValidationES256(ParameterType.TOKEN_ENDPOINT_JWT_VALIDATION);
     }
 
     @Test
-    public void testTokenEndpointJwtParametersES384() throws ResolverException {
+    public void testTokenEndpointJwtParametersES384() throws Exception {
+        initTest(null);
         metaData.setTokenEndpointAuthJWSAlg(JWSAlgorithm.ES384);
         testSigningValidationES384(ParameterType.TOKEN_ENDPOINT_JWT_VALIDATION);
     }
 
     @Test
-    public void testTokenEndpointJwtParametersES512() throws ResolverException {
+    public void testTokenEndpointJwtParametersES512() throws Exception {
+        initTest(null);
         metaData.setTokenEndpointAuthJWSAlg(JWSAlgorithm.ES512);
         testSigningValidationES512(ParameterType.TOKEN_ENDPOINT_JWT_VALIDATION);
     }
 
     @Test
-    public void testTokenEndpointJwtParametersHS256() throws ResolverException {
+    public void testTokenEndpointJwtParametersHS256() throws Exception {
+        initTest(null);
         metaData.setTokenEndpointAuthJWSAlg(JWSAlgorithm.HS256);
         testSigningValidationHS256(ParameterType.TOKEN_ENDPOINT_JWT_VALIDATION);
     }
 
     @Test
-    public void testTokenEndpointJwtParametersHS384() throws ResolverException {
+    public void testTokenEndpointJwtParametersHS384() throws Exception {
+        initTest(null);
         metaData.setTokenEndpointAuthJWSAlg(JWSAlgorithm.HS384);
         testSigningValidationHS384(ParameterType.TOKEN_ENDPOINT_JWT_VALIDATION);
     }
 
     @Test
-    public void testTokenEndpointJwtParametersHS512() throws ResolverException {
+    public void testTokenEndpointJwtParametersHS512() throws Exception {
+        initTest(null);
         metaData.setTokenEndpointAuthJWSAlg(JWSAlgorithm.HS512);
         testSigningValidationHS512(ParameterType.TOKEN_ENDPOINT_JWT_VALIDATION);
     }

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


More information about the commits mailing list