You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by tk...@apache.org on 2017/07/05 19:30:33 UTC

nifi git commit: NIFI-3193: added ability to authenticate using cert common names

Repository: nifi
Updated Branches:
  refs/heads/master 7843b885e -> 47eece579


NIFI-3193: added ability to authenticate using cert common names

This closes #1971.

Signed-off-by: Tony Kurc <tk...@apache.org>
Also reviewed by Pierre Villard <pi...@gmail.com>


Project: http://git-wip-us.apache.org/repos/asf/nifi/repo
Commit: http://git-wip-us.apache.org/repos/asf/nifi/commit/47eece57
Tree: http://git-wip-us.apache.org/repos/asf/nifi/tree/47eece57
Diff: http://git-wip-us.apache.org/repos/asf/nifi/diff/47eece57

Branch: refs/heads/master
Commit: 47eece57980782a245a13c693d0bffc2c78f5695
Parents: 7843b88
Author: m-hogue <ho...@gmail.com>
Authored: Tue Jun 27 16:19:10 2017 -0400
Committer: Tony Kurc <tk...@apache.org>
Committed: Wed Jul 5 15:28:54 2017 -0400

----------------------------------------------------------------------
 .../amqp/processors/AbstractAMQPProcessor.java  | 33 +++++++++++++++-----
 .../additionalDetails.html                      |  3 ++
 .../additionalDetails.html                      |  3 ++
 .../processors/AbstractAMQPProcessorTest.java   | 14 +++++++++
 4 files changed, 45 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/nifi/blob/47eece57/nifi-nar-bundles/nifi-amqp-bundle/nifi-amqp-processors/src/main/java/org/apache/nifi/amqp/processors/AbstractAMQPProcessor.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-amqp-bundle/nifi-amqp-processors/src/main/java/org/apache/nifi/amqp/processors/AbstractAMQPProcessor.java b/nifi-nar-bundles/nifi-amqp-bundle/nifi-amqp-processors/src/main/java/org/apache/nifi/amqp/processors/AbstractAMQPProcessor.java
index af24cb7..efd1be5 100644
--- a/nifi-nar-bundles/nifi-amqp-bundle/nifi-amqp-processors/src/main/java/org/apache/nifi/amqp/processors/AbstractAMQPProcessor.java
+++ b/nifi-nar-bundles/nifi-amqp-bundle/nifi-amqp-processors/src/main/java/org/apache/nifi/amqp/processors/AbstractAMQPProcessor.java
@@ -37,6 +37,8 @@ import org.apache.nifi.ssl.SSLContextService;
 
 import com.rabbitmq.client.Connection;
 import com.rabbitmq.client.ConnectionFactory;
+import com.rabbitmq.client.DefaultSaslConfig;
+
 
 /**
  * Base processor that uses RabbitMQ client API
@@ -97,6 +99,15 @@ abstract class AbstractAMQPProcessor<T extends AMQPWorker> extends AbstractProce
             .required(false)
             .identifiesControllerService(SSLContextService.class)
             .build();
+    public static final PropertyDescriptor USE_CERT_AUTHENTICATION = new PropertyDescriptor.Builder()
+            .name("cert-authentication")
+            .displayName("Use Certificate Authentication")
+            .description("Authenticate using the SSL certificate common name rather than user name/password.")
+            .required(false)
+            .defaultValue("false")
+            .allowableValues("true", "false")
+            .addValidator(StandardValidators.BOOLEAN_VALIDATOR)
+            .build();
     public static final PropertyDescriptor CLIENT_AUTH = new PropertyDescriptor.Builder()
             .name("ssl-client-auth")
             .displayName("Client Auth")
@@ -122,6 +133,7 @@ abstract class AbstractAMQPProcessor<T extends AMQPWorker> extends AbstractProce
         descriptors.add(PASSWORD);
         descriptors.add(AMQP_VERSION);
         descriptors.add(SSL_CONTEXT_SERVICE);
+        descriptors.add(USE_CERT_AUTHENTICATION);
         descriptors.add(CLIENT_AUTH);
     }
 
@@ -218,9 +230,14 @@ abstract class AbstractAMQPProcessor<T extends AMQPWorker> extends AbstractProce
         }
 
         // handles TLS/SSL aspects
+        final Boolean useCertAuthentication = context.getProperty(USE_CERT_AUTHENTICATION).asBoolean();
         final SSLContextService sslService = context.getProperty(SSL_CONTEXT_SERVICE).asControllerService(SSLContextService.class);
+        // if the property to use cert authentication is set but the SSL service hasn't been configured, throw an exception.
+        if (useCertAuthentication && sslService == null) {
+            throw new ProviderCreationException("This processor is configured to use cert authentication, " +
+                    "but the SSL Context Service hasn't been configured. You need to configure the SSL Context Service.");
+        }
         final String rawClientAuth = context.getProperty(CLIENT_AUTH).getValue();
-        final SSLContext sslContext;
 
         if (sslService != null) {
             final SSLContextService.ClientAuth clientAuth;
@@ -234,14 +251,14 @@ abstract class AbstractAMQPProcessor<T extends AMQPWorker> extends AbstractProce
                             rawClientAuth, StringUtils.join(SslContextFactory.ClientAuth.values(), ", ")));
                 }
             }
-            sslContext = sslService.createSSLContext(clientAuth);
-        } else {
-            sslContext = null;
-        }
-
-        // check if the ssl context is set and add it to the factory if so
-        if (sslContext != null) {
+            final SSLContext sslContext = sslService.createSSLContext(clientAuth);
             cf.useSslProtocol(sslContext);
+
+            if (useCertAuthentication) {
+                // this tells the factory to use the cert common name for authentication and not user name and password
+                // REF: https://github.com/rabbitmq/rabbitmq-auth-mechanism-ssl
+                cf.setSaslConfig(DefaultSaslConfig.EXTERNAL);
+            }
         }
 
         try {

http://git-wip-us.apache.org/repos/asf/nifi/blob/47eece57/nifi-nar-bundles/nifi-amqp-bundle/nifi-amqp-processors/src/main/resources/docs/org.apache.nifi.amqp.processors.ConsumeAMQP/additionalDetails.html
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-amqp-bundle/nifi-amqp-processors/src/main/resources/docs/org.apache.nifi.amqp.processors.ConsumeAMQP/additionalDetails.html b/nifi-nar-bundles/nifi-amqp-bundle/nifi-amqp-processors/src/main/resources/docs/org.apache.nifi.amqp.processors.ConsumeAMQP/additionalDetails.html
index f276eeb..8ae8a0f 100644
--- a/nifi-nar-bundles/nifi-amqp-bundle/nifi-amqp-processors/src/main/resources/docs/org.apache.nifi.amqp.processors.ConsumeAMQP/additionalDetails.html
+++ b/nifi-nar-bundles/nifi-amqp-bundle/nifi-amqp-processors/src/main/resources/docs/org.apache.nifi.amqp.processors.ConsumeAMQP/additionalDetails.html
@@ -63,6 +63,9 @@
     <li><b>Password</b> - [REQUIRED] password to use with user name to connect to AMQP broker. 
     Usually provided by the administrator. Defaults to 'guest'.
     </li>
+    <li><b>Use Certificate Authentication</b> - [OPTIONAL] whether or not to use the SSL certificate common name for authentication rather than user name/password.
+    This can only be used in conjunction with SSL. Defaults to 'false'.
+    </li>
     <li><b>Virtual Host</b> - [OPTIONAL] Virtual Host name which segregates AMQP system for enhanced security.
     Please refer to <a href="http://blog.dtzq.com/2012/06/rabbitmq-users-and-virtual-hosts.html">this blog</a> for more details on Virtual Host.
     </li>

http://git-wip-us.apache.org/repos/asf/nifi/blob/47eece57/nifi-nar-bundles/nifi-amqp-bundle/nifi-amqp-processors/src/main/resources/docs/org.apache.nifi.amqp.processors.PublishAMQP/additionalDetails.html
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-amqp-bundle/nifi-amqp-processors/src/main/resources/docs/org.apache.nifi.amqp.processors.PublishAMQP/additionalDetails.html b/nifi-nar-bundles/nifi-amqp-bundle/nifi-amqp-processors/src/main/resources/docs/org.apache.nifi.amqp.processors.PublishAMQP/additionalDetails.html
index 73453b6..7391b39 100644
--- a/nifi-nar-bundles/nifi-amqp-bundle/nifi-amqp-processors/src/main/resources/docs/org.apache.nifi.amqp.processors.PublishAMQP/additionalDetails.html
+++ b/nifi-nar-bundles/nifi-amqp-bundle/nifi-amqp-processors/src/main/resources/docs/org.apache.nifi.amqp.processors.PublishAMQP/additionalDetails.html
@@ -84,6 +84,9 @@
     <li><b>Password</b> - [REQUIRED] password to use with user name to connect to AMQP broker. 
     Usually provided by the administrator. Defaults to 'guest'.
     </li>
+    <li><b>Use Certificate Authentication</b> - [OPTIONAL] whether or not to use the SSL certificate common name for authentication rather than user name/password.
+    This can only be used in conjunction with SSL. Defaults to 'false'.
+    </li>
     <li><b>Virtual Host</b> - [OPTIONAL] Virtual Host name which segregates AMQP system for enhanced security.
     Please refer to <a href="http://blog.dtzq.com/2012/06/rabbitmq-users-and-virtual-hosts.html">this blog</a> for more details on Virtual Host.
     </li>

http://git-wip-us.apache.org/repos/asf/nifi/blob/47eece57/nifi-nar-bundles/nifi-amqp-bundle/nifi-amqp-processors/src/test/java/org/apache/nifi/amqp/processors/AbstractAMQPProcessorTest.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-amqp-bundle/nifi-amqp-processors/src/test/java/org/apache/nifi/amqp/processors/AbstractAMQPProcessorTest.java b/nifi-nar-bundles/nifi-amqp-bundle/nifi-amqp-processors/src/test/java/org/apache/nifi/amqp/processors/AbstractAMQPProcessorTest.java
index be709b3..662e0e5 100644
--- a/nifi-nar-bundles/nifi-amqp-bundle/nifi-amqp-processors/src/test/java/org/apache/nifi/amqp/processors/AbstractAMQPProcessorTest.java
+++ b/nifi-nar-bundles/nifi-amqp-bundle/nifi-amqp-processors/src/test/java/org/apache/nifi/amqp/processors/AbstractAMQPProcessorTest.java
@@ -29,6 +29,7 @@ import org.apache.nifi.util.TestRunners;
 import org.junit.Before;
 import org.junit.Test;
 
+
 /**
  * Unit tests for the AbstractAMQPProcessor class
  */
@@ -50,6 +51,7 @@ public class AbstractAMQPProcessorTest {
         testRunner.addControllerService("ssl-context", sslService);
         testRunner.enableControllerService(sslService);
         testRunner.setProperty(AbstractAMQPProcessor.SSL_CONTEXT_SERVICE, "ssl-context");
+        testRunner.setProperty(AbstractAMQPProcessor.USE_CERT_AUTHENTICATION, "false");
         testRunner.setProperty(AbstractAMQPProcessor.HOST, "test");
         testRunner.setProperty(AbstractAMQPProcessor.PORT, "9999");
         testRunner.setProperty(AbstractAMQPProcessor.USER, "test");
@@ -59,6 +61,17 @@ public class AbstractAMQPProcessorTest {
         processor.onTrigger(testRunner.getProcessContext(), testRunner.getProcessSessionFactory());
     }
 
+    @Test(expected = ProviderCreationException.class)
+    public void testInvalidSSLConfiguration() throws Exception {
+        // it's invalid to have use_cert_auth enabled and not have the SSL Context Service configured
+        testRunner.setProperty(AbstractAMQPProcessor.USE_CERT_AUTHENTICATION, "true");
+        testRunner.setProperty(AbstractAMQPProcessor.HOST, "test");
+        testRunner.setProperty(AbstractAMQPProcessor.PORT, "9999");
+        testRunner.setProperty(AbstractAMQPProcessor.USER, "test");
+        testRunner.setProperty(AbstractAMQPProcessor.PASSWORD, "test");
+        processor.onTrigger(testRunner.getProcessContext(), testRunner.getProcessSessionFactory());
+    }
+
     /**
      * Provides a stubbed processor instance for testing
      */
@@ -67,6 +80,7 @@ public class AbstractAMQPProcessorTest {
         protected void rendezvousWithAmqp(ProcessContext context, ProcessSession session) throws ProcessException {
             // nothing to do
         }
+
         @Override
         protected AMQPConsumer finishBuildingTargetResource(ProcessContext context) {
             return null;