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);

Reply via email to