You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by jo...@apache.org on 2020/09/02 17:59:25 UTC

[nifi] 15/16: NIFI-7730 Added regression tests for multiple certificate keystores. Cleaned up JettyServer code. Changed test logging severity to include debug statements. Added test resources.

This is an automated email from the ASF dual-hosted git repository.

joewitt pushed a commit to branch support/nifi-1.12.x
in repository https://gitbox.apache.org/repos/asf/nifi.git

commit 29fc0a7c9d4652f40eeabaec57676dbb115c84d8
Author: Kotaro Terada <ko...@apache.org>
AuthorDate: Tue Aug 11 18:19:23 2020 +0900

    NIFI-7730 Added regression tests for multiple certificate keystores.
    Cleaned up JettyServer code.
    Changed test logging severity to include debug statements.
    Added test resources.
    
    This closes #4498.
    
    Co-authored-by: Kotaro Terada <ko...@apache.org>
---
 .../nifi/remote/client/http/TestHttpClient.java    |   2 +-
 .../org/apache/nifi/web/server/JettyServer.java    |  14 +--
 .../nifi/web/server/JettyServerGroovyTest.groovy   | 105 +++++++++++++++++----
 .../apache/nifi/web/server/JettyServerTest.java    |  56 +++++------
 .../nifi-jetty/src/test/resources/log4j.properties |   1 +
 .../src/test/resources/multiple_cert_keystore.jks  | Bin 0 -> 4457 bytes
 .../src/test/resources/multiple_cert_keystore.p12  | Bin 0 -> 4949 bytes
 .../nifi/integration/util/NiFiTestServer.java      |   7 +-
 .../reporting/prometheus/PrometheusServer.java     |   2 +-
 .../processors/standard/HandleHttpRequest.java     |   7 +-
 .../nifi/processors/standard/ListenHTTP.java       |   7 +-
 .../processors/standard/TestGetHTTPGroovy.groovy   |   4 +-
 .../processors/standard/TestPostHTTPGroovy.groovy  |   4 +-
 .../java/org/apache/nifi/web/util/TestServer.java  |   7 +-
 .../jetty/AbstractJettyWebSocketService.java       |   2 +-
 .../websocket/example/WebSocketClientExample.java  |   2 +-
 .../websocket/example/WebSocketServerExample.java  |   7 +-
 .../server/TlsCertificateAuthorityService.java     |   7 +-
 18 files changed, 136 insertions(+), 98 deletions(-)

diff --git a/nifi-commons/nifi-site-to-site-client/src/test/java/org/apache/nifi/remote/client/http/TestHttpClient.java b/nifi-commons/nifi-site-to-site-client/src/test/java/org/apache/nifi/remote/client/http/TestHttpClient.java
index f6bf811..ab71c56 100644
--- a/nifi-commons/nifi-site-to-site-client/src/test/java/org/apache/nifi/remote/client/http/TestHttpClient.java
+++ b/nifi-commons/nifi-site-to-site-client/src/test/java/org/apache/nifi/remote/client/http/TestHttpClient.java
@@ -453,7 +453,7 @@ public class TestHttpClient {
         final ServletHandler wrongPathServletHandler = new ServletHandler();
         wrongPathContextHandler.insertHandler(wrongPathServletHandler);
 
-        final SslContextFactory sslContextFactory = new SslContextFactory();
+        final SslContextFactory sslContextFactory = new SslContextFactory.Server();
         sslContextFactory.setKeyStorePath("src/test/resources/certs/keystore.jks");
         sslContextFactory.setKeyStorePassword("passwordpassword");
         sslContextFactory.setKeyStoreType("JKS");
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/main/java/org/apache/nifi/web/server/JettyServer.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/main/java/org/apache/nifi/web/server/JettyServer.java
index ca7944f..e53c785 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/main/java/org/apache/nifi/web/server/JettyServer.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/main/java/org/apache/nifi/web/server/JettyServer.java
@@ -975,19 +975,13 @@ public class JettyServer implements NiFiServer, ExtensionUiLoader {
     }
 
     private SslContextFactory createSslContextFactory() {
-        final SslContextFactory contextFactory = new SslContextFactory();
-        configureSslContextFactory(contextFactory, props);
-        return contextFactory;
+        final SslContextFactory.Server serverContextFactory = new SslContextFactory.Server();
+        configureSslContextFactory(serverContextFactory, props);
+        return serverContextFactory;
     }
 
-    protected static void configureSslContextFactory(SslContextFactory contextFactory, NiFiProperties props) {
-        // Need to set SslContextFactory's endpointIdentificationAlgorithm to null; this is a server,
-        // not a client.  Server does not need to perform hostname verification on the client.
-        // Previous to Jetty 9.4.15.v20190215, this defaulted to null, and now defaults to "HTTPS".
-        contextFactory.setEndpointIdentificationAlgorithm(null);
-
+    protected static void configureSslContextFactory(SslContextFactory.Server contextFactory, NiFiProperties props) {
         // Explicitly exclude legacy TLS protocol versions
-        // contextFactory.setProtocol(CertificateUtils.getHighestCurrentSupportedTlsProtocolVersion());
         contextFactory.setIncludeProtocols(CertificateUtils.getCurrentSupportedTlsProtocolVersions());
         contextFactory.setExcludeProtocols("TLS", "TLSv1", "TLSv1.1", "SSL", "SSLv2", "SSLv2Hello", "SSLv3");
 
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/test/groovy/org/apache/nifi/web/server/JettyServerGroovyTest.groovy b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/test/groovy/org/apache/nifi/web/server/JettyServerGroovyTest.groovy
index 64077a0..054ad08 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/test/groovy/org/apache/nifi/web/server/JettyServerGroovyTest.groovy
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/test/groovy/org/apache/nifi/web/server/JettyServerGroovyTest.groovy
@@ -19,6 +19,9 @@ package org.apache.nifi.web.server
 import org.apache.log4j.AppenderSkeleton
 import org.apache.log4j.spi.LoggingEvent
 import org.apache.nifi.bundle.Bundle
+import org.apache.nifi.nar.ExtensionManagerHolder
+import org.apache.nifi.nar.ExtensionMapping
+import org.apache.nifi.nar.SystemBundle
 import org.apache.nifi.processor.DataUnit
 import org.apache.nifi.properties.StandardNiFiProperties
 import org.apache.nifi.security.util.CertificateUtils
@@ -121,6 +124,8 @@ class JettyServerGroovyTest extends GroovyTestCase {
 
     @After
     void tearDown() throws Exception {
+        // Cleans up the EMH so it can be reinitialized when a new Jetty server starts
+        ExtensionManagerHolder.INSTANCE = null
         TestAppender.reset()
     }
 
@@ -196,10 +201,9 @@ class JettyServerGroovyTest extends GroovyTestCase {
         assert !bothConfigsPresentForHttp
         assert !bothConfigsPresentForHttps
 
-        // Verifies that the warning was not logged
-        assert log.size() == 2
-        assert log.first() == "Both configs present for HTTP properties: false"
-        assert log.last() == "Both configs present for HTTPS properties: false"
+        // Verifies that the warning was not logged (messages are duplicated because of log4j.properties settings)
+        assert log.size() == 4
+        assert log.every { it =~ "Both configs present for HTTPS? properties: false" }
     }
 
     @Test
@@ -242,10 +246,84 @@ class JettyServerGroovyTest extends GroovyTestCase {
         // Assertions defined above
     }
 
+    /**
+     * Regression test added after NiFi 1.12.0 because Jetty upgrade to 9.4.26 no longer works
+     * with multiple certificate keystores.
+     */
+    @Test
+    void testShouldStartWithMultipleCertificatePKCS12Keystore() {
+        // Arrange
+        final String externalHostname = "localhost"
+
+        NiFiProperties httpsProps = new StandardNiFiProperties(rawProperties: new Properties([
+                (NiFiProperties.WEB_HTTPS_PORT): HTTPS_PORT as String,
+                (NiFiProperties.WEB_HTTPS_HOST): externalHostname,
+                (NiFiProperties.SECURITY_KEYSTORE): "src/test/resources/multiple_cert_keystore.p12",
+                (NiFiProperties.SECURITY_KEYSTORE_PASSWD): "passwordpassword",
+                (NiFiProperties.SECURITY_KEYSTORE_TYPE): "PKCS12",
+                (NiFiProperties.NAR_LIBRARY_DIRECTORY): "target/"
+        ]))
+
+        JettyServer jetty = createJettyServer(httpsProps)
+        Server internalServer = jetty.server
+        List<Connector> connectors = Arrays.asList(internalServer.connectors)
+
+        // Act
+        jetty.start()
+
+        // Assert
+        assertServerConnector(connectors, "TLS", CURRENT_TLS_PROTOCOL_VERSIONS, CURRENT_TLS_PROTOCOL_VERSIONS, externalHostname, HTTPS_PORT)
+
+        // Clean up
+        jetty.stop()
+    }
+
+    /**
+     * Regression test added after NiFi 1.12.0 because Jetty upgrade to 9.4.26 no longer works
+     * with multiple certificate keystores.
+     */
+    @Test
+    void testShouldStartWithMultipleCertificateJKSKeystore() {
+        // Arrange
+        final String externalHostname = "localhost"
+
+        NiFiProperties httpsProps = new StandardNiFiProperties(rawProperties: new Properties([
+                (NiFiProperties.WEB_HTTPS_PORT): HTTPS_PORT as String,
+                (NiFiProperties.WEB_HTTPS_HOST): externalHostname,
+                (NiFiProperties.SECURITY_KEYSTORE): "src/test/resources/multiple_cert_keystore.jks",
+                (NiFiProperties.SECURITY_KEYSTORE_PASSWD): "passwordpassword",
+                (NiFiProperties.SECURITY_KEYSTORE_TYPE): "JKS",
+                (NiFiProperties.NAR_LIBRARY_DIRECTORY): "target/"
+        ]))
+
+        JettyServer jetty = createJettyServer(httpsProps)
+        Server internalServer = jetty.server
+        List<Connector> connectors = Arrays.asList(internalServer.connectors)
+
+        // Act
+        jetty.start()
+
+        // Assert
+        assertServerConnector(connectors, "TLS", CURRENT_TLS_PROTOCOL_VERSIONS, CURRENT_TLS_PROTOCOL_VERSIONS, externalHostname, HTTPS_PORT)
+
+        // Clean up
+        jetty.stop()
+    }
+
+    private static JettyServer createJettyServer(StandardNiFiProperties httpsProps) {
+        Server internalServer = new Server()
+        JettyServer jetty = new JettyServer(internalServer, httpsProps)
+        jetty.systemBundle = SystemBundle.create(httpsProps)
+        jetty.bundles = [] as Set<Bundle>
+        jetty.extensionMapping = [size: { -> 0 }] as ExtensionMapping
+        jetty.configureHttpsConnector(internalServer, new HttpConfiguration())
+        jetty
+    }
+
     @Test
     void testShouldConfigureHTTPSConnector() {
         // Arrange
-        final String externalHostname = "secure.host.com"
+        final String externalHostname = "localhost"
 
         NiFiProperties httpsProps = new StandardNiFiProperties(rawProperties: new Properties([
                 (NiFiProperties.WEB_HTTPS_PORT): HTTPS_PORT as String,
@@ -260,9 +338,7 @@ class JettyServerGroovyTest extends GroovyTestCase {
         List<Connector> connectors = Arrays.asList(internalServer.connectors)
 
         // Assert
-
-        // Set the expected TLS protocols to null because no actual keystore/truststore is loaded here
-        assertServerConnector(connectors, "TLS", null, null, externalHostname, HTTPS_PORT)
+        assertServerConnector(connectors, "TLS", CURRENT_TLS_PROTOCOL_VERSIONS, CURRENT_TLS_PROTOCOL_VERSIONS, externalHostname, HTTPS_PORT)
     }
 
     @Test
@@ -411,16 +487,13 @@ class JettyServerGroovyTest extends GroovyTestCase {
         assert connector.port == EXPECTED_PORT
         assert connector.getProtocols() == ['ssl', 'http/1.1']
 
-        // This kind of testing is not ideal as it breaks encapsulation, but is necessary to enforce verification of the TLS protocol versions specified
         SslConnectionFactory connectionFactory = connector.getConnectionFactory("ssl") as SslConnectionFactory
-        SslContextFactory sslContextFactory = connectionFactory._sslContextFactory as SslContextFactory
+        SslContextFactory sslContextFactory = connectionFactory.getSslContextFactory()
         logger.debug("SSL Context Factory: ${sslContextFactory.dump()}")
 
-        // Using the getters is subject to NPE due to blind array copies
-        assert sslContextFactory._sslProtocol == EXPECTED_TLS_PROTOCOL
-        assert sslContextFactory._includeProtocols.containsAll(EXPECTED_INCLUDED_PROTOCOLS ?: Collections.emptySet())
-        assert (sslContextFactory._excludeProtocols as List<String>).containsAll(LEGACY_TLS_PROTOCOLS)
-        assert sslContextFactory._selectedProtocols == EXPECTED_SELECTED_PROTOCOLS as String[]
+        assert sslContextFactory.getProtocol() == EXPECTED_TLS_PROTOCOL
+        assert Arrays.asList(sslContextFactory.getIncludeProtocols()).containsAll(EXPECTED_INCLUDED_PROTOCOLS ?: Collections.emptySet())
+        assert (sslContextFactory.getExcludeProtocols() as List<String>).containsAll(LEGACY_TLS_PROTOCOLS)
     }
 
     @Test
@@ -531,4 +604,4 @@ class TestAppender extends AppenderSkeleton {
             events.collect { LoggingEvent le -> le.getRenderedMessage() }
         }
     }
-}
\ No newline at end of file
+}
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/test/java/org/apache/nifi/web/server/JettyServerTest.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/test/java/org/apache/nifi/web/server/JettyServerTest.java
index d25980a..63e9ad5 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/test/java/org/apache/nifi/web/server/JettyServerTest.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/test/java/org/apache/nifi/web/server/JettyServerTest.java
@@ -43,12 +43,12 @@ public class JettyServerTest {
         addProps.put(NiFiProperties.SECURITY_KEYSTORE_PASSWD, testKeystorePassword);
         addProps.put(NiFiProperties.SECURITY_KEY_PASSWD, testKeyPassword);
         NiFiProperties nifiProperties = NiFiProperties.createBasicNiFiProperties(null, addProps);
-        SslContextFactory contextFactory = mock(SslContextFactory.class);
+        SslContextFactory.Server mockSCF = mock(SslContextFactory.Server.class);
 
-        JettyServer.configureSslContextFactory(contextFactory, nifiProperties);
+        JettyServer.configureSslContextFactory(mockSCF, nifiProperties);
 
-        verify(contextFactory).setKeyStorePassword(testKeystorePassword);
-        verify(contextFactory).setKeyManagerPassword(testKeyPassword);
+        verify(mockSCF).setKeyStorePassword(testKeystorePassword);
+        verify(mockSCF).setKeyManagerPassword(testKeyPassword);
     }
 
     @Test
@@ -59,12 +59,12 @@ public class JettyServerTest {
         final Map<String, String> addProps = new HashMap<>();
         addProps.put(NiFiProperties.SECURITY_KEY_PASSWD, testKeyPassword);
         NiFiProperties nifiProperties = NiFiProperties.createBasicNiFiProperties(null, addProps);
-        SslContextFactory contextFactory = mock(SslContextFactory.class);
+        SslContextFactory.Server mockSCF = mock(SslContextFactory.Server.class);
 
-        JettyServer.configureSslContextFactory(contextFactory, nifiProperties);
+        JettyServer.configureSslContextFactory(mockSCF, nifiProperties);
 
-        verify(contextFactory).setKeyManagerPassword(testKeyPassword);
-        verify(contextFactory, never()).setKeyStorePassword(anyString());
+        verify(mockSCF).setKeyManagerPassword(testKeyPassword);
+        verify(mockSCF, never()).setKeyStorePassword(anyString());
     }
 
     @Test
@@ -75,12 +75,12 @@ public class JettyServerTest {
         final Map<String, String> addProps = new HashMap<>();
         addProps.put(NiFiProperties.SECURITY_KEYSTORE_PASSWD, testKeystorePassword);
         NiFiProperties nifiProperties = NiFiProperties.createBasicNiFiProperties(null, addProps);
-        SslContextFactory contextFactory = mock(SslContextFactory.class);
+        SslContextFactory.Server mockSCF = mock(SslContextFactory.Server.class);
 
-        JettyServer.configureSslContextFactory(contextFactory, nifiProperties);
+        JettyServer.configureSslContextFactory(mockSCF, nifiProperties);
 
-        verify(contextFactory).setKeyStorePassword(testKeystorePassword);
-        verify(contextFactory).setKeyManagerPassword(testKeystorePassword);
+        verify(mockSCF).setKeyStorePassword(testKeystorePassword);
+        verify(mockSCF).setKeyManagerPassword(testKeystorePassword);
     }
 
     @Test
@@ -90,12 +90,12 @@ public class JettyServerTest {
         String keyStoreType = KeystoreType.JKS.toString();
         addProps.put(NiFiProperties.SECURITY_KEYSTORE_TYPE, keyStoreType);
         NiFiProperties nifiProperties = NiFiProperties.createBasicNiFiProperties(null, addProps);
-        SslContextFactory contextFactory = mock(SslContextFactory.class);
+        SslContextFactory.Server mockSCF = mock(SslContextFactory.Server.class);
 
-        JettyServer.configureSslContextFactory(contextFactory, nifiProperties);
+        JettyServer.configureSslContextFactory(mockSCF, nifiProperties);
 
-        verify(contextFactory).setKeyStoreType(keyStoreType);
-        verify(contextFactory).setKeyStoreProvider(SUN_PROVIDER_NAME);
+        verify(mockSCF).setKeyStoreType(keyStoreType);
+        verify(mockSCF).setKeyStoreProvider(SUN_PROVIDER_NAME);
     }
 
     @Test
@@ -105,12 +105,12 @@ public class JettyServerTest {
         String keyStoreType = KeystoreType.PKCS12.toString();
         addProps.put(NiFiProperties.SECURITY_KEYSTORE_TYPE, keyStoreType);
         NiFiProperties nifiProperties = NiFiProperties.createBasicNiFiProperties(null, addProps);
-        SslContextFactory contextFactory = mock(SslContextFactory.class);
+        SslContextFactory.Server mockSCF = mock(SslContextFactory.Server.class);
 
-        JettyServer.configureSslContextFactory(contextFactory, nifiProperties);
+        JettyServer.configureSslContextFactory(mockSCF, nifiProperties);
 
-        verify(contextFactory).setKeyStoreType(keyStoreType);
-        verify(contextFactory).setKeyStoreProvider(BouncyCastleProvider.PROVIDER_NAME);
+        verify(mockSCF).setKeyStoreType(keyStoreType);
+        verify(mockSCF).setKeyStoreProvider(BouncyCastleProvider.PROVIDER_NAME);
     }
 
     @Test
@@ -120,12 +120,12 @@ public class JettyServerTest {
         String trustStoreType = KeystoreType.JKS.toString();
         addProps.put(NiFiProperties.SECURITY_TRUSTSTORE_TYPE, trustStoreType);
         NiFiProperties nifiProperties = NiFiProperties.createBasicNiFiProperties(null, addProps);
-        SslContextFactory contextFactory = mock(SslContextFactory.class);
+        SslContextFactory.Server mockSCF = mock(SslContextFactory.Server.class);
 
-        JettyServer.configureSslContextFactory(contextFactory, nifiProperties);
+        JettyServer.configureSslContextFactory(mockSCF, nifiProperties);
 
-        verify(contextFactory).setTrustStoreType(trustStoreType);
-        verify(contextFactory).setTrustStoreProvider(SUN_PROVIDER_NAME);
+        verify(mockSCF).setTrustStoreType(trustStoreType);
+        verify(mockSCF).setTrustStoreProvider(SUN_PROVIDER_NAME);
     }
 
     @Test
@@ -135,11 +135,11 @@ public class JettyServerTest {
         String trustStoreType = KeystoreType.PKCS12.toString();
         addProps.put(NiFiProperties.SECURITY_TRUSTSTORE_TYPE, trustStoreType);
         NiFiProperties nifiProperties = NiFiProperties.createBasicNiFiProperties(null, addProps);
-        SslContextFactory contextFactory = mock(SslContextFactory.class);
+        SslContextFactory.Server mockSCF = mock(SslContextFactory.Server.class);
 
-        JettyServer.configureSslContextFactory(contextFactory, nifiProperties);
+        JettyServer.configureSslContextFactory(mockSCF, nifiProperties);
 
-        verify(contextFactory).setTrustStoreType(trustStoreType);
-        verify(contextFactory).setTrustStoreProvider(BouncyCastleProvider.PROVIDER_NAME);
+        verify(mockSCF).setTrustStoreType(trustStoreType);
+        verify(mockSCF).setTrustStoreProvider(BouncyCastleProvider.PROVIDER_NAME);
     }
 }
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/test/resources/log4j.properties b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/test/resources/log4j.properties
index 162521f..2d5c71c 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/test/resources/log4j.properties
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/test/resources/log4j.properties
@@ -16,6 +16,7 @@
 #
 
 log4j.rootLogger=INFO,console,test
+log4j.logger.org.apache.nifi.web=DEBUG,console,test
 
 log4j.appender.console=org.apache.log4j.ConsoleAppender
 log4j.appender.console.Target=System.err
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/test/resources/multiple_cert_keystore.jks b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/test/resources/multiple_cert_keystore.jks
new file mode 100644
index 0000000..e563d45
Binary files /dev/null and b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/test/resources/multiple_cert_keystore.jks differ
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/test/resources/multiple_cert_keystore.p12 b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/test/resources/multiple_cert_keystore.p12
new file mode 100644
index 0000000..2bdec71
Binary files /dev/null and b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/test/resources/multiple_cert_keystore.p12 differ
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/integration/util/NiFiTestServer.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/integration/util/NiFiTestServer.java
index 9379019..e61dbae 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/integration/util/NiFiTestServer.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/integration/util/NiFiTestServer.java
@@ -77,12 +77,7 @@ public class NiFiTestServer {
 
     // TODO: Refactor this method to use proper factory methods
     private void createSecureConnector() {
-        org.eclipse.jetty.util.ssl.SslContextFactory contextFactory = new org.eclipse.jetty.util.ssl.SslContextFactory();
-
-        // Need to set SslContextFactory's endpointIdentificationAlgorithm to null; this is a server,
-        // not a client.  Server does not need to perform hostname verification on the client.
-        // Previous to Jetty 9.4.15.v20190215, this defaulted to null, and now defaults to "HTTPS".
-        contextFactory.setEndpointIdentificationAlgorithm(null);
+        org.eclipse.jetty.util.ssl.SslContextFactory contextFactory = new org.eclipse.jetty.util.ssl.SslContextFactory.Server();
 
         // require client auth when not supporting login or anonymous access
         if (StringUtils.isBlank(properties.getProperty(NiFiProperties.SECURITY_USER_LOGIN_IDENTITY_PROVIDER))) {
diff --git a/nifi-nar-bundles/nifi-prometheus-bundle/nifi-prometheus-reporting-task/src/main/java/org/apache/nifi/reporting/prometheus/PrometheusServer.java b/nifi-nar-bundles/nifi-prometheus-bundle/nifi-prometheus-reporting-task/src/main/java/org/apache/nifi/reporting/prometheus/PrometheusServer.java
index 50d5ee1..d57f1c1 100644
--- a/nifi-nar-bundles/nifi-prometheus-bundle/nifi-prometheus-reporting-task/src/main/java/org/apache/nifi/reporting/prometheus/PrometheusServer.java
+++ b/nifi-nar-bundles/nifi-prometheus-bundle/nifi-prometheus-reporting-task/src/main/java/org/apache/nifi/reporting/prometheus/PrometheusServer.java
@@ -113,7 +113,7 @@ public class PrometheusServer {
     }
 
     private SslContextFactory createSslFactory(final SSLContextService sslService, boolean needClientAuth, boolean wantClientAuth) {
-        SslContextFactory sslFactory = new SslContextFactory();
+        SslContextFactory sslFactory = new SslContextFactory.Server();
 
         sslFactory.setNeedClientAuth(needClientAuth);
         sslFactory.setWantClientAuth(wantClientAuth);
diff --git a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/HandleHttpRequest.java b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/HandleHttpRequest.java
index a7d3c89..dbdb995ea 100644
--- a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/HandleHttpRequest.java
+++ b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/HandleHttpRequest.java
@@ -520,18 +520,13 @@ public class HandleHttpRequest extends AbstractProcessor {
     }
 
     private SslContextFactory createSslFactory(final SSLContextService sslService, final boolean needClientAuth, final boolean wantClientAuth) {
-        final SslContextFactory sslFactory = new SslContextFactory();
+        final SslContextFactory sslFactory = new SslContextFactory.Server();
 
         sslFactory.setNeedClientAuth(needClientAuth);
         sslFactory.setWantClientAuth(wantClientAuth);
 
         sslFactory.setProtocol(sslService.getSslAlgorithm());
 
-        // Need to set SslContextFactory's endpointIdentificationAlgorithm to null; this is a server,
-        // not a client.  Server does not need to perform hostname verification on the client.
-        // Previous to Jetty 9.4.15.v20190215, this defaulted to null.
-        sslFactory.setEndpointIdentificationAlgorithm(null);
-
         if (sslService.isKeyStoreConfigured()) {
             sslFactory.setKeyStorePath(sslService.getKeyStoreFile());
             sslFactory.setKeyStorePassword(sslService.getKeyStorePassword());
diff --git a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/ListenHTTP.java b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/ListenHTTP.java
index af17a6e..cfc1a2a 100644
--- a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/ListenHTTP.java
+++ b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/ListenHTTP.java
@@ -256,14 +256,9 @@ public class ListenHTTP extends AbstractSessionFactoryProcessor {
 
         final boolean needClientAuth = sslContextService != null && sslContextService.getTrustStoreFile() != null;
 
-        final SslContextFactory contextFactory = new SslContextFactory();
+        final SslContextFactory contextFactory = new SslContextFactory.Server();
         contextFactory.setNeedClientAuth(needClientAuth);
 
-        // Need to set SslContextFactory's endpointIdentificationAlgorithm to null; this is a server,
-        // not a client.  Server does not need to perform hostname verification on the client.
-        // Previous to Jetty 9.4.15.v20190215, this defaulted to null, and now defaults to "HTTPS".
-        contextFactory.setEndpointIdentificationAlgorithm(null);
-
         if (needClientAuth) {
             contextFactory.setTrustStorePath(sslContextService.getTrustStoreFile());
             contextFactory.setTrustStoreType(sslContextService.getTrustStoreType());
diff --git a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/groovy/org/apache/nifi/processors/standard/TestGetHTTPGroovy.groovy b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/groovy/org/apache/nifi/processors/standard/TestGetHTTPGroovy.groovy
index e8266f5..a01874d 100644
--- a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/groovy/org/apache/nifi/processors/standard/TestGetHTTPGroovy.groovy
+++ b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/groovy/org/apache/nifi/processors/standard/TestGetHTTPGroovy.groovy
@@ -141,7 +141,7 @@ class TestGetHTTPGroovy extends GroovyTestCase {
 
     private
     static SslContextFactory createSslContextFactory(List supportedProtocols = DEFAULT_PROTOCOLS, List supportedCipherSuites = DEFAULT_CIPHER_SUITES) {
-        final SslContextFactory contextFactory = new SslContextFactory()
+        final SslContextFactory contextFactory = new SslContextFactory.Server()
         contextFactory.needClientAuth = false
         contextFactory.wantClientAuth = false
 
@@ -485,4 +485,4 @@ class TestGetHTTPGroovy extends GroovyTestCase {
         runner.clearTransferState()
         logger.info("Ran successfully")
     }
-}
\ No newline at end of file
+}
diff --git a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/groovy/org/apache/nifi/processors/standard/TestPostHTTPGroovy.groovy b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/groovy/org/apache/nifi/processors/standard/TestPostHTTPGroovy.groovy
index be38cd3..8b96bdc 100644
--- a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/groovy/org/apache/nifi/processors/standard/TestPostHTTPGroovy.groovy
+++ b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/groovy/org/apache/nifi/processors/standard/TestPostHTTPGroovy.groovy
@@ -133,7 +133,7 @@ class TestPostHTTPGroovy extends GroovyTestCase {
 
     private
     static SslContextFactory createSslContextFactory(List supportedProtocols = DEFAULT_PROTOCOLS, List supportedCipherSuites = DEFAULT_CIPHER_SUITES) {
-        final SslContextFactory contextFactory = new SslContextFactory()
+        final SslContextFactory contextFactory = new SslContextFactory.Server()
         contextFactory.needClientAuth = false
         contextFactory.wantClientAuth = false
 
@@ -440,4 +440,4 @@ class TestPostHTTPGroovy extends GroovyTestCase {
         runner.clearTransferState()
         logger.info("Ran successfully")
     }
-}
\ No newline at end of file
+}
diff --git a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-web-test-utils/src/main/java/org/apache/nifi/web/util/TestServer.java b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-web-test-utils/src/main/java/org/apache/nifi/web/util/TestServer.java
index 23e128b..e691d6b 100644
--- a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-web-test-utils/src/main/java/org/apache/nifi/web/util/TestServer.java
+++ b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-web-test-utils/src/main/java/org/apache/nifi/web/util/TestServer.java
@@ -76,7 +76,7 @@ public class TestServer {
     }
 
     private void createSecureConnector(final Map<String, String> sslProperties) {
-        SslContextFactory ssl = new SslContextFactory();
+        SslContextFactory ssl = new SslContextFactory.Server();
 
         if (sslProperties.get(StandardSSLContextService.KEYSTORE.getName()) != null) {
             ssl.setKeyStorePath(sslProperties.get(StandardSSLContextService.KEYSTORE.getName()));
@@ -97,11 +97,6 @@ public class TestServer {
             ssl.setNeedClientAuth(Boolean.parseBoolean(clientAuth));
         }
 
-        // Need to set SslContextFactory's endpointIdentificationAlgorithm to null; this is a server,
-        // not a client.  Server does not need to perform hostname verification on the client.
-        // Previous to Jetty 9.4.15.v20190215, this defaulted to null, and now defaults to "HTTPS".
-        ssl.setEndpointIdentificationAlgorithm(null);
-
         // build the connector
         final ServerConnector https = new ServerConnector(jetty, ssl);
 
diff --git a/nifi-nar-bundles/nifi-websocket-bundle/nifi-websocket-services-jetty/src/main/java/org/apache/nifi/websocket/jetty/AbstractJettyWebSocketService.java b/nifi-nar-bundles/nifi-websocket-bundle/nifi-websocket-services-jetty/src/main/java/org/apache/nifi/websocket/jetty/AbstractJettyWebSocketService.java
index 546a853..abff785 100644
--- a/nifi-nar-bundles/nifi-websocket-bundle/nifi-websocket-services-jetty/src/main/java/org/apache/nifi/websocket/jetty/AbstractJettyWebSocketService.java
+++ b/nifi-nar-bundles/nifi-websocket-bundle/nifi-websocket-services-jetty/src/main/java/org/apache/nifi/websocket/jetty/AbstractJettyWebSocketService.java
@@ -67,7 +67,7 @@ public abstract class AbstractJettyWebSocketService extends AbstractWebSocketSer
 
 
     protected SslContextFactory createSslFactory(final SSLContextService sslService, final boolean needClientAuth, final boolean wantClientAuth, final String endpointIdentificationAlgorithm) {
-        final SslContextFactory sslFactory = new SslContextFactory();
+        final SslContextFactory sslFactory = new SslContextFactory.Server();
 
         sslFactory.setNeedClientAuth(needClientAuth);
         sslFactory.setWantClientAuth(wantClientAuth);
diff --git a/nifi-nar-bundles/nifi-websocket-bundle/nifi-websocket-services-jetty/src/test/java/org/apache/nifi/websocket/example/WebSocketClientExample.java b/nifi-nar-bundles/nifi-websocket-bundle/nifi-websocket-services-jetty/src/test/java/org/apache/nifi/websocket/example/WebSocketClientExample.java
index f8c9b3a..f222bc2 100644
--- a/nifi-nar-bundles/nifi-websocket-bundle/nifi-websocket-services-jetty/src/test/java/org/apache/nifi/websocket/example/WebSocketClientExample.java
+++ b/nifi-nar-bundles/nifi-websocket-bundle/nifi-websocket-services-jetty/src/test/java/org/apache/nifi/websocket/example/WebSocketClientExample.java
@@ -46,7 +46,7 @@ public class WebSocketClientExample {
         String destUri = "wss://localhost:50010/test";
 
         final CountDownLatch replyLatch = new CountDownLatch(1);
-        final SslContextFactory sslContextFactory = new SslContextFactory();
+        final SslContextFactory sslContextFactory = new SslContextFactory.Client();
         sslContextFactory.setKeyStorePath("src/test/resources/certs/keystore.jks");
         sslContextFactory.setKeyStorePassword("passwordpassword");
         sslContextFactory.setKeyStoreType("JKS");
diff --git a/nifi-nar-bundles/nifi-websocket-bundle/nifi-websocket-services-jetty/src/test/java/org/apache/nifi/websocket/example/WebSocketServerExample.java b/nifi-nar-bundles/nifi-websocket-bundle/nifi-websocket-services-jetty/src/test/java/org/apache/nifi/websocket/example/WebSocketServerExample.java
index dad8520..913031a 100644
--- a/nifi-nar-bundles/nifi-websocket-bundle/nifi-websocket-services-jetty/src/test/java/org/apache/nifi/websocket/example/WebSocketServerExample.java
+++ b/nifi-nar-bundles/nifi-websocket-bundle/nifi-websocket-services-jetty/src/test/java/org/apache/nifi/websocket/example/WebSocketServerExample.java
@@ -152,16 +152,11 @@ public class WebSocketServerExample {
         httpConnector = new ServerConnector(server);
         httpConnector.setPort(50010);
 
-        final SslContextFactory sslContextFactory = new SslContextFactory();
+        final SslContextFactory sslContextFactory = new SslContextFactory.Server();
         sslContextFactory.setKeyStorePath("src/test/resources/certs/keystore.jks");
         sslContextFactory.setKeyStorePassword("passwordpassword");
         sslContextFactory.setKeyStoreType("JKS");
 
-        // Need to set SslContextFactory's endpointIdentificationAlgorithm to null; this is a server,
-        // not a client.  Server does not need to perform hostname verification on the client.
-        // Previous to Jetty 9.4.15.v20190215, this defaulted to null, and now defaults to "HTTPS".
-        sslContextFactory.setEndpointIdentificationAlgorithm(null);
-
         final HttpConfiguration https = new HttpConfiguration();
         https.addCustomizer(new SecureRequestCustomizer());
         sslConnector = new ServerConnector(server,
diff --git a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/service/server/TlsCertificateAuthorityService.java b/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/service/server/TlsCertificateAuthorityService.java
index 7b6d1e2..d95ae8e 100644
--- a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/service/server/TlsCertificateAuthorityService.java
+++ b/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/service/server/TlsCertificateAuthorityService.java
@@ -62,16 +62,11 @@ public class TlsCertificateAuthorityService {
     private static Server createServer(Handler handler, int port, KeyStore keyStore, String keyPassword) throws Exception {
         Server server = new Server();
 
-        SslContextFactory sslContextFactory = new SslContextFactory();
+        SslContextFactory sslContextFactory = new SslContextFactory.Server();
         sslContextFactory.setIncludeProtocols(CertificateUtils.getHighestCurrentSupportedTlsProtocolVersion());
         sslContextFactory.setKeyStore(keyStore);
         sslContextFactory.setKeyManagerPassword(keyPassword);
 
-        // Need to set SslContextFactory's endpointIdentificationAlgorithm to null; this is a server,
-        // not a client.  Server does not need to perform hostname verification on the client.
-        // Previous to Jetty 9.4.15.v20190215, this defaulted to null, and now defaults to "HTTPS".
-        sslContextFactory.setEndpointIdentificationAlgorithm(null);
-
         HttpConfiguration httpsConfig = new HttpConfiguration();
         httpsConfig.addCustomizer(new SecureRequestCustomizer());