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 91f7d72645 NIFI-15032 Added Key Pair Authentication to Snowflake
Connection Pool
91f7d72645 is described below
commit 91f7d726457ad3c1dcc1cc2962cee17f3b3515d9
Author: exceptionfactory <[email protected]>
AuthorDate: Wed Oct 1 12:46:37 2025 -0500
NIFI-15032 Added Key Pair Authentication to Snowflake Connection Pool
Signed-off-by: Pierre Villard <[email protected]>
This closes #10363.
---
.../service/SnowflakeComputingConnectionPool.java | 25 ++++++++++++++++++++++
1 file changed, 25 insertions(+)
diff --git
a/nifi-extension-bundles/nifi-snowflake-bundle/nifi-snowflake-services/src/main/java/org/apache/nifi/snowflake/service/SnowflakeComputingConnectionPool.java
b/nifi-extension-bundles/nifi-snowflake-bundle/nifi-snowflake-services/src/main/java/org/apache/nifi/snowflake/service/SnowflakeComputingConnectionPool.java
index faa6dc4d65..e03838b64c 100644
---
a/nifi-extension-bundles/nifi-snowflake-bundle/nifi-snowflake-services/src/main/java/org/apache/nifi/snowflake/service/SnowflakeComputingConnectionPool.java
+++
b/nifi-extension-bundles/nifi-snowflake-bundle/nifi-snowflake-services/src/main/java/org/apache/nifi/snowflake/service/SnowflakeComputingConnectionPool.java
@@ -27,6 +27,7 @@ import org.apache.nifi.annotation.documentation.Tags;
import org.apache.nifi.annotation.lifecycle.OnDisabled;
import org.apache.nifi.annotation.lifecycle.OnEnabled;
import org.apache.nifi.components.PropertyDescriptor;
+import org.apache.nifi.components.PropertyValue;
import org.apache.nifi.components.ValidationContext;
import org.apache.nifi.components.ValidationResult;
import org.apache.nifi.controller.ConfigurationContext;
@@ -35,6 +36,7 @@ import org.apache.nifi.dbcp.utils.DBCPProperties;
import org.apache.nifi.dbcp.utils.DataSourceConfiguration;
import org.apache.nifi.expression.AttributeExpression;
import org.apache.nifi.expression.ExpressionLanguageScope;
+import org.apache.nifi.key.service.api.PrivateKeyService;
import org.apache.nifi.oauth2.OAuth2AccessTokenProvider;
import org.apache.nifi.processor.exception.ProcessException;
import org.apache.nifi.processor.util.StandardValidators;
@@ -47,15 +49,18 @@ import org.apache.nifi.reporting.InitializationException;
import org.apache.nifi.snowflake.service.util.ConnectionUrlFormat;
import org.apache.nifi.snowflake.service.util.ConnectionUrlFormatParameters;
+import java.security.PrivateKey;
import java.sql.Connection;
import java.sql.Driver;
import java.sql.DriverManager;
+import java.util.Base64;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import static net.snowflake.client.core.SFSessionProperty.AUTHENTICATOR;
+import static net.snowflake.client.core.SFSessionProperty.PRIVATE_KEY_BASE64;
import static net.snowflake.client.core.SFSessionProperty.TOKEN;
import static org.apache.nifi.dbcp.utils.DBCPProperties.DB_PASSWORD;
import static org.apache.nifi.dbcp.utils.DBCPProperties.DB_USER;
@@ -140,6 +145,13 @@ public class SnowflakeComputingConnectionPool extends
AbstractDBCPConnectionPool
.description("The password for the Snowflake user.")
.build();
+ public static final PropertyDescriptor PRIVATE_KEY_SERVICE = new
PropertyDescriptor.Builder()
+ .name("Private Key Service")
+ .description("Provides RSA Private Key for Key Pair
Authentication")
+ .identifiesControllerService(PrivateKeyService.class)
+ .required(false)
+ .build();
+
public static final PropertyDescriptor ACCESS_TOKEN_PROVIDER = new
PropertyDescriptor.Builder()
.name("OAuth2 Access Token Provider")
.description("Service providing OAuth2 Access Tokens for
authenticating using the HTTP Authorization Header")
@@ -154,6 +166,8 @@ public class SnowflakeComputingConnectionPool extends
AbstractDBCPConnectionPool
.expressionLanguageSupported(ExpressionLanguageScope.ENVIRONMENT)
.build();
+ private static final String AUTHENTICATOR_SNOWFLAKE_JWT = "SNOWFLAKE_JWT";
+
private volatile OAuth2AccessTokenProvider accessTokenProvider;
private static final List<PropertyDescriptor> PROPERTY_DESCRIPTORS =
List.of(
@@ -169,6 +183,7 @@ public class SnowflakeComputingConnectionPool extends
AbstractDBCPConnectionPool
SnowflakeProperties.DATABASE,
SnowflakeProperties.SCHEMA,
SNOWFLAKE_WAREHOUSE,
+ PRIVATE_KEY_SERVICE,
ACCESS_TOKEN_PROVIDER,
ProxyConfigurationService.PROXY_CONFIGURATION_SERVICE,
VALIDATION_QUERY,
@@ -291,6 +306,16 @@ public class SnowflakeComputingConnectionPool extends
AbstractDBCPConnectionPool
connectionProperties.put(TOKEN.getPropertyKey(),
tokenProvider.getAccessDetails().getAccessToken());
}
+ final PropertyValue privateKeyServiceProperty =
context.getProperty(PRIVATE_KEY_SERVICE);
+ if (privateKeyServiceProperty.isSet()) {
+ final PrivateKeyService privateKeyService =
privateKeyServiceProperty.asControllerService(PrivateKeyService.class);
+ final PrivateKey privateKey = privateKeyService.getPrivateKey();
+ final byte[] privateKeyEncoded = privateKey.getEncoded();
+ final String privateKeyBase64 =
Base64.getEncoder().encodeToString(privateKeyEncoded);
+ connectionProperties.put(PRIVATE_KEY_BASE64.getPropertyKey(),
privateKeyBase64);
+ connectionProperties.put(AUTHENTICATOR.getPropertyKey(),
AUTHENTICATOR_SNOWFLAKE_JWT);
+ }
+
final ProxyConfigurationService proxyConfigurationService = context
.getProperty(ProxyConfigurationService.PROXY_CONFIGURATION_SERVICE)
.asControllerService(ProxyConfigurationService.class);