[java-idp-oidc] 01/02: JCOMOIDC-6 Move common crypto/security code from the OIDC plugin
Henri Mikkonen
henri.mikkonen at iki.fi
Fri Nov 27 17:32:25 UTC 2020
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=b1f0e40239c3618f0b6f57f4646b5477639cd788
commit b1f0e40239c3618f0b6f57f4646b5477639cd788
Author: Henri Mikkonen <henri.mikkonen at iki.fi>
AuthorDate: Fri Nov 27 19:25:40 2020 +0200
JCOMOIDC-6 Move common crypto/security code from the OIDC plugin
https://issues.shibboleth.net/jira/browse/JCOMOIDC-6
Moved remote JSON Web Key (JWK) cache and utilities from java-oidc-common.
---
.../oidc/metadata/resolver/RemoteJwkSetCache.java | 179 ---------------------
.../oidc/metadata/support/RemoteJwkUtils.java | 106 ------------
.../metadata/resolver/RemoteJwkSetCacheTest.java | 138 ----------------
.../impl/FilesystemClientInformationResolver.java | 2 +-
.../StorageServiceClientInformationResolver.java | 2 +-
.../oidc/profile/impl/AddJwksToClientMetadata.java | 2 +-
6 files changed, 3 insertions(+), 426 deletions(-)
diff --git a/idp-oidc-extension-api/src/main/java/org/geant/idpextension/oidc/metadata/resolver/RemoteJwkSetCache.java b/idp-oidc-extension-api/src/main/java/org/geant/idpextension/oidc/metadata/resolver/RemoteJwkSetCache.java
deleted file mode 100644
index 3a49cb82..00000000
--- a/idp-oidc-extension-api/src/main/java/org/geant/idpextension/oidc/metadata/resolver/RemoteJwkSetCache.java
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * Copyright (c) 2017 - 2020, GÉANT
- *
- * Licensed under the Apache License, Version 2.0 (the “License”); you may not
- * use this file except in compliance with the License. You may obtain a copy
- * of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an “AS IS” BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.geant.idpextension.oidc.metadata.resolver;
-
-import java.io.IOException;
-import java.net.URI;
-import java.time.Instant;
-
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-
-import org.apache.http.client.HttpClient;
-import org.geant.idpextension.oidc.metadata.support.RemoteJwkUtils;
-import org.opensaml.security.httpclient.HttpClientSecurityParameters;
-import org.opensaml.storage.StorageCapabilities;
-import org.opensaml.storage.StorageCapabilitiesEx;
-import org.opensaml.storage.StorageRecord;
-import org.opensaml.storage.StorageService;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.nimbusds.jose.jwk.JWKSet;
-
-import net.shibboleth.utilities.java.support.annotation.constraint.NonnullAfterInit;
-import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
-import net.shibboleth.utilities.java.support.component.AbstractIdentifiableInitializableComponent;
-import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
-import net.shibboleth.utilities.java.support.component.ComponentSupport;
-import net.shibboleth.utilities.java.support.logic.Constraint;
-
-/**
- * Stores fetched remote key set values for a desired period of time.
- */
-public class RemoteJwkSetCache extends AbstractIdentifiableInitializableComponent {
-
- /** The context name in the {@link StorageService}. */
- public static final String CONTEXT_NAME = "oidcRemoteJwkSetContents";
-
- /** Logger. */
- private final Logger log = LoggerFactory.getLogger(RemoteJwkSetCache.class);
-
- /** Backing storage for the remote JWK set contents. */
- private StorageService storage;
-
- /** The {@link HttpClient} to use. */
- @NonnullAfterInit private HttpClient httpClient;
-
- /** HTTP client security parameters. */
- @Nullable private HttpClientSecurityParameters httpClientSecurityParameters;
-
- /**
- * Get the backing store for the remote JWK set contents.
- *
- * @return the backing store.
- */
- @NonnullAfterInit
- public StorageService getStorage() {
- return storage;
- }
-
- /**
- * Set the backing store for the remote JWK set contents.
- *
- * @param storageService backing store to use
- */
- public void setStorage(@Nonnull final StorageService storageService) {
- ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
-
- storage = Constraint.isNotNull(storageService, "StorageService cannot be null");
- final StorageCapabilities caps = storage.getCapabilities();
- if (caps instanceof StorageCapabilitiesEx) {
- Constraint.isTrue(((StorageCapabilitiesEx) caps).isServerSide(), "StorageService cannot be client-side");
- }
- }
-
- /**
- * Set the {@link HttpClient} to use.
- *
- * @param client client to use
- */
- public void setHttpClient(@Nonnull final HttpClient client) {
- ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
- ComponentSupport.ifDestroyedThrowDestroyedComponentException(this);
-
- httpClient = Constraint.isNotNull(client, "HttpClient cannot be null");
- }
-
- /**
- * Set the optional client security parameters.
- *
- * @param params the new client security parameters
- */
- public void setHttpClientSecurityParameters(@Nullable final HttpClientSecurityParameters params) {
- ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
- ComponentSupport.ifDestroyedThrowDestroyedComponentException(this);
-
- httpClientSecurityParameters = params;
- }
-
- /** {@inheritDoc} */
- @Override
- public void doInitialize() throws ComponentInitializationException {
- if (storage == null) {
- throw new ComponentInitializationException("StorageService cannot be null");
- }
- if (httpClient == null) {
- throw new ComponentInitializationException("HttpClient cannot be null");
- }
- }
-
- /**
- * Returns remote JWK set if found from the cache, otherwise fetches and stores it.
- *
- * @param uri value to check
- * @param expires time for disposal of value from cache
- *
- * @return JWK set, null if not found from the cache and cannot be fetched.
- */
- public JWKSet fetch(@Nonnull final URI uri, @Nonnull final Instant expires) {
- return fetch(CONTEXT_NAME, uri, expires);
- }
-
- /**
- * Returns remote JWK set if found from the cache, otherwise fetches and stores it.
- *
- * @param context a context label to subdivide the cache
- * @param uri value to check
- * @param expires time (in milliseconds since beginning of epoch) for disposal of value from cache
- *
- * @return JWK set, null if not found from the cache and cannot be fetched.
- */
- @Nullable public JWKSet fetch(@Nonnull @NotEmpty final String context, @Nonnull final URI uri,
- @Nonnull final Instant expires) {
- final String key = uri.toString();
-
- final StorageCapabilities caps = storage.getCapabilities();
- if (context.length() > caps.getContextSize()) {
- log.error("context {} too long for StorageService (limit {})", context, caps.getContextSize());
- return null;
- }
-
- try {
- final StorageRecord<?> entry = storage.read(context, key);
- if (entry == null) {
- log.debug("Value '{}' was not in the cache, fetching it", key);
- final JWKSet remoteJwkSet = RemoteJwkUtils.fetchRemoteJwkSet("RemoteJwkSetCache", uri, httpClient,
- httpClientSecurityParameters);
- if (remoteJwkSet != null && remoteJwkSet.getKeys() != null && !remoteJwkSet.getKeys().isEmpty()) {
- storage.create(context, key, remoteJwkSet.toString(), expires.toEpochMilli());
- return remoteJwkSet;
- } else {
- log.warn("Could not find any remote keys from {}", key);
- }
- } else {
- final JWKSet cachedSet = JWKSet.parse(entry.getValue());
- log.debug("Cached value found and will be returned, expires at {}", entry.getExpiration());
- return cachedSet;
- }
- } catch (final IOException | java.text.ParseException e) {
- log.error("Exception reading/writing to storage service", e);
- }
-
- return null;
- }
-}
diff --git a/idp-oidc-extension-api/src/main/java/org/geant/idpextension/oidc/metadata/support/RemoteJwkUtils.java b/idp-oidc-extension-api/src/main/java/org/geant/idpextension/oidc/metadata/support/RemoteJwkUtils.java
deleted file mode 100644
index eb29cd0c..00000000
--- a/idp-oidc-extension-api/src/main/java/org/geant/idpextension/oidc/metadata/support/RemoteJwkUtils.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (c) 2017 - 2020, GÉANT
- *
- * Licensed under the Apache License, Version 2.0 (the “License”); you may not
- * use this file except in compliance with the License. You may obtain a copy
- * of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an “AS IS” BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.geant.idpextension.oidc.metadata.support;
-
-import java.io.IOException;
-import java.net.URI;
-
-import org.apache.http.HttpResponse;
-import org.apache.http.ParseException;
-import org.apache.http.client.HttpClient;
-import org.apache.http.client.methods.HttpUriRequest;
-import org.apache.http.client.methods.RequestBuilder;
-import org.apache.http.client.protocol.HttpClientContext;
-import org.apache.http.util.EntityUtils;
-import org.opensaml.security.httpclient.HttpClientSecurityParameters;
-import org.opensaml.security.httpclient.HttpClientSecuritySupport;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.nimbusds.jose.jwk.JWKSet;
-import com.nimbusds.jose.util.JSONObjectUtils;
-
-import net.minidev.json.JSONObject;
-
-/**
- * Generic utility methods related to remote JWK sets.
- */
-public final class RemoteJwkUtils {
-
- /**
- * Constructor.
- */
- private RemoteJwkUtils() {
- // prevented
- }
-
- /**
- * Fetches the JWK set from the given URI using the given client and security parameters.
- *
- * @param logPrefix log prefix
- * @param uri the endpoint for the JWK set.
- * @param httpClient HTTP client
- * @param httpClientSecurityParameters security parameters
- *
- * @return The JWK set fetched from the endpoint, or null if it couldn't be fetched.
- */
- public static JWKSet fetchRemoteJwkSet(final String logPrefix, final URI uri, final HttpClient httpClient,
- final HttpClientSecurityParameters httpClientSecurityParameters) {
- final Logger log = LoggerFactory.getLogger(RemoteJwkUtils.class);
- final HttpResponse response;
- try {
- final HttpUriRequest get = RequestBuilder.get().setUri(uri).build();
- final HttpClientContext clientContext = HttpClientContext.create();
- HttpClientSecuritySupport.marshalSecurityParameters(clientContext, httpClientSecurityParameters, true);
- HttpClientSecuritySupport.addDefaultTLSTrustEngineCriteria(clientContext, get);
- response = httpClient.execute(get, clientContext);
- HttpClientSecuritySupport.checkTLSCredentialEvaluated(clientContext, get.getURI().getScheme());
- } catch (final IOException e) {
- log.error("{} Could not get the JWK contents from {}", logPrefix, uri, e);
- return null;
- }
- if (response == null) {
- log.error("{} Could not get the JWK contents from {}", logPrefix, uri);
- return null;
- }
- final String output;
- try {
- output = EntityUtils.toString(response.getEntity(), "UTF-8");
- } catch (final ParseException | IOException e) {
- log.error("{} Could not parse the JWK contents from {}", logPrefix, uri);
- return null;
- } finally {
- EntityUtils.consumeQuietly(response.getEntity());
- }
- log.trace("{} Fetched the following response body: {}", logPrefix, output);
- final JWKSet jwkSet;
- try {
- final JSONObject json = JSONObjectUtils.parse(output);
- // The following check is needed to avoid NPE from Nimbus if keys claim not found
- if (JSONObjectUtils.getJSONArray(json, "keys") == null) {
- log.error("{} Could not find 'keys' array from the JSON from {}", logPrefix, uri);
- return null;
- }
- jwkSet = JWKSet.parse(json);
- } catch (final java.text.ParseException e) {
- log.error("{} Could not parse the contents from {}", logPrefix, uri, e);
- return null;
- }
- return jwkSet;
- }
-
-}
diff --git a/idp-oidc-extension-api/src/test/java/org/geant/idpextension/oidc/metadata/resolver/RemoteJwkSetCacheTest.java b/idp-oidc-extension-api/src/test/java/org/geant/idpextension/oidc/metadata/resolver/RemoteJwkSetCacheTest.java
deleted file mode 100644
index 439761fb..00000000
--- a/idp-oidc-extension-api/src/test/java/org/geant/idpextension/oidc/metadata/resolver/RemoteJwkSetCacheTest.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright (c) 2017 - 2020, GÉANT
- *
- * Licensed under the Apache License, Version 2.0 (the “License”); you may not
- * use this file except in compliance with the License. You may obtain a copy
- * of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an “AS IS” BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.geant.idpextension.oidc.metadata.resolver;
-
-import java.io.IOException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.time.Instant;
-
-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.impl.client.HttpClientBuilder;
-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.testng.Assert;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import com.nimbusds.jose.jwk.JWKSet;
-
-import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
-
-/**
- * Unit tests for {@link RemoteJwkSetCache}.
- */
-public class RemoteJwkSetCacheTest {
-
- RemoteJwkSetCache jwkSetCache;
- StorageService storageService;
- HttpClient httpClient;
-
-
- @BeforeMethod
- public void setup() throws InitializationException, ComponentInitializationException {
- jwkSetCache = new RemoteJwkSetCache();
- storageService = buildStorageService();
- }
-
- protected StorageService buildStorageService() throws ComponentInitializationException {
- MemoryStorageService storageService = new MemoryStorageService();
- storageService.setId("mockId");
- storageService.initialize();
- return storageService;
- }
-
- @Test(expectedExceptions = ComponentInitializationException.class)
- public void testNoHttpClient() throws ComponentInitializationException {
- jwkSetCache.setStorage(storageService);
- jwkSetCache.initialize();
- }
-
- @Test(expectedExceptions = ComponentInitializationException.class)
- public void testNoStorageService() throws ComponentInitializationException {
- jwkSetCache.setHttpClient(HttpClientBuilder.create().build());
- jwkSetCache.initialize();
- }
-
- @Test
- public void testSuccessNoSecurity() throws ClientProtocolException, IOException, ComponentInitializationException,
- URISyntaxException, InterruptedException {
- jwkSetCache.setStorage(storageService);
- jwkSetCache.setHttpClient(createMockHttpClient(validJwkSet()));
- jwkSetCache.setHttpClientSecurityParameters(null);
- jwkSetCache.initialize();
- final String uri = "http://example.org";
- System.out.println(new URI(uri).toString());
- JWKSet jwkSet = jwkSetCache.fetch(new URI(uri), Instant.now().plusSeconds(5));
- Assert.assertNotNull(jwkSet);
- Assert.assertNotNull(jwkSetCache.getStorage().read(RemoteJwkSetCache.CONTEXT_NAME, uri));
- jwkSet = jwkSetCache.fetch(new URI(uri), Instant.now().plusSeconds(5));
- Assert.assertNotNull(jwkSet);
- Thread.sleep(5001);
- Assert.assertNull(storageService.read(RemoteJwkSetCache.CONTEXT_NAME, uri));
- }
-
- @Test
- public void testInvalidJwk() throws ClientProtocolException, IOException, ComponentInitializationException,
- URISyntaxException {
- jwkSetCache.setStorage(storageService);
- jwkSetCache.setHttpClient(createMockHttpClient("not_jwk_set"));
- jwkSetCache.initialize();
- final JWKSet jwkSet = jwkSetCache.fetch(new URI("http://example.org"), Instant.now().plusSeconds(5));
- Assert.assertNull(jwkSet);
- }
-
- protected HttpClient createMockHttpClient(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;
- }
-
- protected String validJwkSet() {
- return "{\n" +
- " \"keys\": [\n" +
- " {\n" +
- " \"kid\": \"08d3245c62f86b6362afcbbffe1d069826dd1dc1\",\n" +
- " \"e\": \"AQAB\",\n" +
- " \"kty\": \"RSA\",\n" +
- " \"alg\": \"RS256\",\n" +
- " \"n\": \"mSLCSG1hK28xrzcSfgbvRinkIRjecBlwsQggynHppHiiT6I80waivIqTJBSFYyVuRCAHXi6apSsL5FUWKd42GOhVUayIyzvuz1CqTuh5a9ACXaJjEVLUFO39QfXxWrxhpSJCTN9aMkdtoV1QJqfAd3IF9MYwfojsoEn3d5XX5TX4RxqZ9-HGbgSLsRuAzFIg9NxxfTYhbECBskhhR4RIcam-1T52FafmK2LMiuIEDPiVg6LvAqWi8gdMRd8WhiP_ZIRJTCH4C0NFKmw1PZyKadVxvwg97vwPTF8qkFdwJ_kjQAMmq77PxankluAkfWjFqbD4JepO4HH3aJvU8Sl_Ow\",\n" +
- " \"use\": \"sig\"\n" +
- " },\n" +
- " {\n" +
- " \"alg\": \"RS256\",\n" +
- " \"n\": \"uS9Iep_r83oLpfnMXLnB5a8IVUP7ZRreM1rxNWYnaqEQr1NfRisyIi4cYG7KbWiuLCmRQOD7ybhpdHCcN9ty5evz4irWT5hIa98Jr3a2BISTskBbPmBgUR3_TuQ_fvxeQYCCETJUcho5gXK-yeDWJwcD2iwqpVzIZHz8BBe5AYFUlJMzwgzYMe9aqoOEWVv__Gd7Z_kaz5pa0lOsWUUPNFmeW4e4rtNvosx7ItyyyghIyG2KX-0phOgbfzG6Ub6qA9upBYK9KBtjcoe1ciV-Yn_3HaS5PlugYTo1zYnng1mW7UP5A_QT_HgDqD1clcz0WIEL6usVMRay87ECEmOhrw\",\n" +
- " \"use\": \"sig\",\n" +
- " \"kid\": \"b15a2b8f7a6b3f6bc08bc1c56a88410e146d01fd\",\n" +
- " \"e\": \"AQAB\",\n" +
- " \"kty\": \"RSA\"\n" +
- " }\n" +
- " ]\n" +
- "}";
- }
-
-}
diff --git a/idp-oidc-extension-impl/src/main/java/org/geant/idpextension/oidc/metadata/impl/FilesystemClientInformationResolver.java b/idp-oidc-extension-impl/src/main/java/org/geant/idpextension/oidc/metadata/impl/FilesystemClientInformationResolver.java
index acbb7df4..20ef79c9 100644
--- a/idp-oidc-extension-impl/src/main/java/org/geant/idpextension/oidc/metadata/impl/FilesystemClientInformationResolver.java
+++ b/idp-oidc-extension-impl/src/main/java/org/geant/idpextension/oidc/metadata/impl/FilesystemClientInformationResolver.java
@@ -31,7 +31,6 @@ import javax.annotation.Nullable;
import org.geant.idpextension.oidc.criterion.ClientIDCriterion;
import org.geant.idpextension.oidc.metadata.resolver.ClientInformationResolver;
import org.geant.idpextension.oidc.metadata.resolver.RefreshableClientInformationResolver;
-import org.geant.idpextension.oidc.metadata.resolver.RemoteJwkSetCache;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.Resource;
@@ -44,6 +43,7 @@ import com.nimbusds.openid.connect.sdk.rp.OIDCClientInformation;
import net.minidev.json.JSONArray;
import net.minidev.json.JSONObject;
+import net.shibboleth.oidc.jwk.RemoteJwkSetCache;
import net.shibboleth.utilities.java.support.annotation.constraint.Positive;
import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
import net.shibboleth.utilities.java.support.component.ComponentSupport;
diff --git a/idp-oidc-extension-impl/src/main/java/org/geant/idpextension/oidc/metadata/impl/StorageServiceClientInformationResolver.java b/idp-oidc-extension-impl/src/main/java/org/geant/idpextension/oidc/metadata/impl/StorageServiceClientInformationResolver.java
index f52f9666..360c4e90 100644
--- a/idp-oidc-extension-impl/src/main/java/org/geant/idpextension/oidc/metadata/impl/StorageServiceClientInformationResolver.java
+++ b/idp-oidc-extension-impl/src/main/java/org/geant/idpextension/oidc/metadata/impl/StorageServiceClientInformationResolver.java
@@ -29,7 +29,6 @@ import javax.annotation.Nullable;
import org.geant.idpextension.oidc.criterion.ClientIDCriterion;
import org.geant.idpextension.oidc.metadata.resolver.ClientInformationResolver;
-import org.geant.idpextension.oidc.metadata.resolver.RemoteJwkSetCache;
import org.opensaml.storage.StorageRecord;
import org.opensaml.storage.StorageService;
import org.slf4j.Logger;
@@ -39,6 +38,7 @@ import com.nimbusds.oauth2.sdk.ParseException;
import com.nimbusds.oauth2.sdk.util.JSONObjectUtils;
import com.nimbusds.openid.connect.sdk.rp.OIDCClientInformation;
+import net.shibboleth.oidc.jwk.RemoteJwkSetCache;
import net.shibboleth.utilities.java.support.annotation.constraint.NonnullAfterInit;
import net.shibboleth.utilities.java.support.annotation.constraint.Positive;
import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
diff --git a/idp-oidc-extension-impl/src/main/java/org/geant/idpextension/oidc/profile/impl/AddJwksToClientMetadata.java b/idp-oidc-extension-impl/src/main/java/org/geant/idpextension/oidc/profile/impl/AddJwksToClientMetadata.java
index ca2de161..9a265939 100644
--- a/idp-oidc-extension-impl/src/main/java/org/geant/idpextension/oidc/profile/impl/AddJwksToClientMetadata.java
+++ b/idp-oidc-extension-impl/src/main/java/org/geant/idpextension/oidc/profile/impl/AddJwksToClientMetadata.java
@@ -23,7 +23,6 @@ import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import org.apache.http.client.HttpClient;
-import org.geant.idpextension.oidc.metadata.support.RemoteJwkUtils;
import org.opensaml.profile.action.ActionSupport;
import org.opensaml.profile.action.EventIds;
import org.opensaml.profile.context.ProfileRequestContext;
@@ -34,6 +33,7 @@ import org.slf4j.LoggerFactory;
import com.nimbusds.jose.jwk.JWK;
import com.nimbusds.jose.jwk.JWKSet;
+import net.shibboleth.oidc.jwk.support.RemoteJwkUtils;
import net.shibboleth.utilities.java.support.annotation.constraint.NonnullAfterInit;
import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
import net.shibboleth.utilities.java.support.component.ComponentSupport;
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list