This is an automated email from the ASF dual-hosted git repository.
pvillard pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/nifi.git
The following commit(s) were added to refs/heads/main by this push:
new 19bac11438 NIFI-14061 Added support for file scheme in OIDC Discovery
URL
19bac11438 is described below
commit 19bac1143807ba7ce440feb3eff7bad89c4c9a23
Author: exceptionfactory <[email protected]>
AuthorDate: Sat Dec 14 11:20:34 2024 -0600
NIFI-14061 Added support for file scheme in OIDC Discovery URL
Signed-off-by: Pierre Villard <[email protected]>
This closes #9580.
---
.../src/main/asciidoc/administration-guide.adoc | 3 +-
.../StandardClientRegistrationProvider.java | 29 ++++++--
.../StandardClientRegistrationProviderTest.java | 78 ++++++++++++++++------
3 files changed, 85 insertions(+), 25 deletions(-)
diff --git a/nifi-docs/src/main/asciidoc/administration-guide.adoc
b/nifi-docs/src/main/asciidoc/administration-guide.adoc
index c315e9f5ed..75a4030fcf 100644
--- a/nifi-docs/src/main/asciidoc/administration-guide.adoc
+++ b/nifi-docs/src/main/asciidoc/administration-guide.adoc
@@ -569,7 +569,8 @@ OpenID Connect integration supports the following settings
in _nifi.properties_.
[options="header"]
|==================================================================================================================================================
| Property Name | Description
-|`nifi.security.user.oidc.discovery.url` | The
link:http://openid.net/specs/openid-connect-discovery-1_0.html[Discovery
Configuration URL^] for the OpenID Connect Provider
+|`nifi.security.user.oidc.discovery.url` | The
link:http://openid.net/specs/openid-connect-discovery-1_0.html[Discovery
Configuration URL^]
+ for the OpenID
Connect Provider. Supports URLs with `https` or `file` schemes.
|`nifi.security.user.oidc.connect.timeout` | Socket Connect
timeout when communicating with the OpenID Connect Provider. The default value
is `5 secs`
|`nifi.security.user.oidc.read.timeout` | Socket Read
timeout when communicating with the OpenID Connect Provider. The default value
is `5 secs`
|`nifi.security.user.oidc.client.id` | The Client ID
for NiFi registered with the OpenID Connect Provider
diff --git
a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/oidc/registration/StandardClientRegistrationProvider.java
b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/oidc/registration/StandardClientRegistrationProvider.java
index 40491d1085..c4731ab8e3 100644
---
a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/oidc/registration/StandardClientRegistrationProvider.java
+++
b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/oidc/registration/StandardClientRegistrationProvider.java
@@ -33,6 +33,10 @@ import
org.springframework.security.oauth2.core.oidc.IdTokenClaimNames;
import org.springframework.security.oauth2.core.oidc.OidcScopes;
import org.springframework.web.client.RestClient;
+import java.net.URI;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedHashMap;
@@ -51,6 +55,8 @@ public class StandardClientRegistrationProvider implements
ClientRegistrationPro
private static final Set<String> STANDARD_SCOPES =
Collections.unmodifiableSet(new
LinkedHashSet<>(Arrays.asList(OidcScopes.OPENID, OidcScopes.EMAIL)));
+ private static final String FILE_URI_SCHEME = "file";
+
private final NiFiProperties properties;
private final RestClient restClient;
@@ -107,13 +113,26 @@ public class StandardClientRegistrationProvider
implements ClientRegistrationPro
private OIDCProviderMetadata getProviderMetadata() {
final String discoveryUrl = properties.getOidcDiscoveryUrl();
+ final URI discoveryUri = URI.create(discoveryUrl);
+ final String discoveryUriScheme = discoveryUri.getScheme();
final String metadataObject;
- try {
- metadataObject =
restClient.get().uri(discoveryUrl).retrieve().body(String.class);
- } catch (final RuntimeException e) {
- final String message = String.format("OpenID Connect Metadata URL
[%s] retrieval failed", discoveryUrl);
- throw new OidcConfigurationException(message, e);
+
+ if (FILE_URI_SCHEME.equals(discoveryUriScheme)) {
+ try {
+ final Path discoveryPath = Paths.get(discoveryUri);
+ metadataObject = Files.readString(discoveryPath);
+ } catch (final Exception e) {
+ final String message = String.format("OpenID Connect Metadata
File URI [%s] read failed", discoveryUrl);
+ throw new OidcConfigurationException(message, e);
+ }
+ } else {
+ try {
+ metadataObject =
restClient.get().uri(discoveryUrl).retrieve().body(String.class);
+ } catch (final RuntimeException e) {
+ final String message = String.format("OpenID Connect Metadata
URL [%s] retrieval failed", discoveryUrl);
+ throw new OidcConfigurationException(message, e);
+ }
}
try {
diff --git
a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/test/java/org/apache/nifi/web/security/oidc/registration/StandardClientRegistrationProviderTest.java
b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/test/java/org/apache/nifi/web/security/oidc/registration/StandardClientRegistrationProviderTest.java
index 896d3f8194..3e22dc432f 100644
---
a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/test/java/org/apache/nifi/web/security/oidc/registration/StandardClientRegistrationProviderTest.java
+++
b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/test/java/org/apache/nifi/web/security/oidc/registration/StandardClientRegistrationProviderTest.java
@@ -24,6 +24,7 @@ import org.apache.nifi.util.NiFiProperties;
import org.apache.nifi.web.security.oidc.OidcConfigurationException;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.jupiter.api.io.TempDir;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import
org.springframework.security.oauth2.client.registration.ClientRegistration;
@@ -31,7 +32,10 @@ import
org.springframework.security.oauth2.core.AuthenticationMethod;
import org.springframework.security.oauth2.core.oidc.OidcScopes;
import org.springframework.web.client.RestClient;
+import java.io.IOException;
import java.net.URI;
+import java.nio.file.Files;
+import java.nio.file.Path;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedHashSet;
@@ -71,6 +75,10 @@ class StandardClientRegistrationProviderTest {
private static final String INVALID_CONFIGURATION = "{}";
+ private static final String OPENID_CONFIGURATION_PREFIX =
"openid-configuration";
+
+ private static final String OPENID_CONFIGURATION_EXTENSION = ".json";
+
@Mock
RestClient restClient;
@@ -82,7 +90,7 @@ class StandardClientRegistrationProviderTest {
@Test
void testGetClientRegistration() {
- final NiFiProperties properties = getProperties();
+ final NiFiProperties properties = getProperties(DISCOVERY_URL);
final StandardClientRegistrationProvider provider = new
StandardClientRegistrationProvider(properties, restClient);
final OIDCProviderMetadata providerMetadata = getProviderMetadata();
@@ -95,28 +103,40 @@ class StandardClientRegistrationProviderTest {
final ClientRegistration clientRegistration =
provider.getClientRegistration();
- assertNotNull(clientRegistration);
- assertEquals(CLIENT_ID, clientRegistration.getClientId());
- assertEquals(CLIENT_SECRET, clientRegistration.getClientSecret());
+ assertClientRegistrationFound(clientRegistration);
+ }
- final ClientRegistration.ProviderDetails providerDetails =
clientRegistration.getProviderDetails();
- assertEquals(ISSUER, providerDetails.getIssuerUri());
- assertEquals(JWK_SET_URI.toString(), providerDetails.getJwkSetUri());
- assertEquals(AUTHORIZATION_ENDPOINT_URI.toString(),
providerDetails.getAuthorizationUri());
- assertEquals(TOKEN_ENDPOINT_URI.toString(),
providerDetails.getTokenUri());
+ @Test
+ void testGetClientRegistrationFileUri(@TempDir final Path tempDir) throws
IOException {
+ final OIDCProviderMetadata providerMetadata = getProviderMetadata();
+ final String serializedMetadata = providerMetadata.toString();
- final ClientRegistration.ProviderDetails.UserInfoEndpoint
userInfoEndpoint = providerDetails.getUserInfoEndpoint();
- assertEquals(USER_INFO_URI.toString(), userInfoEndpoint.getUri());
- assertEquals(USER_NAME_ATTRIBUTE_NAME,
userInfoEndpoint.getUserNameAttributeName());
- assertEquals(AuthenticationMethod.HEADER,
userInfoEndpoint.getAuthenticationMethod());
+ final Path configurationPath = Files.createTempFile(tempDir,
OPENID_CONFIGURATION_PREFIX, OPENID_CONFIGURATION_EXTENSION);
+ Files.writeString(configurationPath, serializedMetadata);
+ final String discoveryUrl = configurationPath.toUri().toString();
- final Set<String> scopes = clientRegistration.getScopes();
- assertEquals(EXPECTED_SCOPES, scopes);
+ final NiFiProperties properties = getProperties(discoveryUrl);
+ final StandardClientRegistrationProvider provider = new
StandardClientRegistrationProvider(properties, restClient);
+
+ final ClientRegistration clientRegistration =
provider.getClientRegistration();
+
+ assertClientRegistrationFound(clientRegistration);
+ }
+
+ @Test
+ void testGetClientRegistrationFileUriFailed(@TempDir final Path tempDir) {
+ final Path configurationPath =
tempDir.resolve(OPENID_CONFIGURATION_PREFIX);
+ final String discoveryUrl = configurationPath.toUri().toString();
+
+ final NiFiProperties properties = getProperties(discoveryUrl);
+ final StandardClientRegistrationProvider provider = new
StandardClientRegistrationProvider(properties, restClient);
+
+ assertThrows(OidcConfigurationException.class,
provider::getClientRegistration);
}
@Test
void testGetClientRegistrationRetrievalFailed() {
- final NiFiProperties properties = getProperties();
+ final NiFiProperties properties = getProperties(DISCOVERY_URL);
final StandardClientRegistrationProvider provider = new
StandardClientRegistrationProvider(properties, restClient);
doReturn(requestHeadersUriSpec).when(restClient).get();
@@ -128,7 +148,7 @@ class StandardClientRegistrationProviderTest {
@Test
void testGetClientRegistrationParsingFailed() {
- final NiFiProperties properties = getProperties();
+ final NiFiProperties properties = getProperties(DISCOVERY_URL);
final StandardClientRegistrationProvider provider = new
StandardClientRegistrationProvider(properties, restClient);
doReturn(requestHeadersUriSpec).when(restClient).get();
@@ -139,9 +159,29 @@ class StandardClientRegistrationProviderTest {
assertThrows(OidcConfigurationException.class,
provider::getClientRegistration);
}
- private NiFiProperties getProperties() {
+ private void assertClientRegistrationFound(final ClientRegistration
clientRegistration) {
+ assertNotNull(clientRegistration);
+ assertEquals(CLIENT_ID, clientRegistration.getClientId());
+ assertEquals(CLIENT_SECRET, clientRegistration.getClientSecret());
+
+ final ClientRegistration.ProviderDetails providerDetails =
clientRegistration.getProviderDetails();
+ assertEquals(ISSUER, providerDetails.getIssuerUri());
+ assertEquals(JWK_SET_URI.toString(), providerDetails.getJwkSetUri());
+ assertEquals(AUTHORIZATION_ENDPOINT_URI.toString(),
providerDetails.getAuthorizationUri());
+ assertEquals(TOKEN_ENDPOINT_URI.toString(),
providerDetails.getTokenUri());
+
+ final ClientRegistration.ProviderDetails.UserInfoEndpoint
userInfoEndpoint = providerDetails.getUserInfoEndpoint();
+ assertEquals(USER_INFO_URI.toString(), userInfoEndpoint.getUri());
+ assertEquals(USER_NAME_ATTRIBUTE_NAME,
userInfoEndpoint.getUserNameAttributeName());
+ assertEquals(AuthenticationMethod.HEADER,
userInfoEndpoint.getAuthenticationMethod());
+
+ final Set<String> scopes = clientRegistration.getScopes();
+ assertEquals(EXPECTED_SCOPES, scopes);
+ }
+
+ private NiFiProperties getProperties(final String discoveryUrl) {
final Properties properties = new Properties();
- properties.put(NiFiProperties.SECURITY_USER_OIDC_DISCOVERY_URL,
DISCOVERY_URL);
+ properties.put(NiFiProperties.SECURITY_USER_OIDC_DISCOVERY_URL,
discoveryUrl);
properties.put(NiFiProperties.SECURITY_USER_OIDC_CLIENT_ID, CLIENT_ID);
properties.put(NiFiProperties.SECURITY_USER_OIDC_CLIENT_SECRET,
CLIENT_SECRET);
properties.put(NiFiProperties.SECURITY_USER_OIDC_CLAIM_IDENTIFYING_USER,
USER_NAME_ATTRIBUTE_NAME);