You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by bb...@apache.org on 2019/07/29 19:48:24 UTC

[nifi-registry] branch master updated: NIFIREG-296 - Upgraded Jetty version to 9.4.19.v20190610. Required some changes to integration tests. Minor JettyServer change. - Used jetty.version parameter for test scope dependency - Added comments and removed explicit call to setEndpointIdentificationAlgorithm(null). This is called by SslContextFactory.Server()

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

bbende pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nifi-registry.git


The following commit(s) were added to refs/heads/master by this push:
     new 20ff8d7  NIFIREG-296 - Upgraded Jetty version to 9.4.19.v20190610. Required some changes to integration tests. Minor JettyServer change. - Used jetty.version parameter for test scope dependency - Added comments and removed explicit call to setEndpointIdentificationAlgorithm(null). This is called by SslContextFactory.Server()
20ff8d7 is described below

commit 20ff8d78488285bf70d23189e1ba5a46906b83c1
Author: thenatog <th...@gmail.com>
AuthorDate: Fri Jul 26 17:15:08 2019 -0400

    NIFIREG-296 - Upgraded Jetty version to 9.4.19.v20190610. Required some changes to integration tests. Minor JettyServer change.
    - Used jetty.version parameter for test scope dependency
    - Added comments and removed explicit call to setEndpointIdentificationAlgorithm(null). This is called by SslContextFactory.Server()
    
    This closes #208.
    
    Signed-off-by: Bryan Bende <bb...@apache.org>
---
 .../apache/nifi/registry/jetty/JettyServer.java    |   2 +-
 nifi-registry-core/nifi-registry-web-api/pom.xml   |   6 +
 .../nifi/registry/web/JettyITServerCustomizer.java | 132 +++++++++++++++++++++
 pom.xml                                            |   2 +-
 4 files changed, 140 insertions(+), 2 deletions(-)

diff --git a/nifi-registry-core/nifi-registry-jetty/src/main/java/org/apache/nifi/registry/jetty/JettyServer.java b/nifi-registry-core/nifi-registry-jetty/src/main/java/org/apache/nifi/registry/jetty/JettyServer.java
index 0eb6d88..45619f7 100644
--- a/nifi-registry-core/nifi-registry-jetty/src/main/java/org/apache/nifi/registry/jetty/JettyServer.java
+++ b/nifi-registry-core/nifi-registry-jetty/src/main/java/org/apache/nifi/registry/jetty/JettyServer.java
@@ -167,7 +167,7 @@ public class JettyServer {
     }
 
     private SslContextFactory createSslContextFactory() {
-        final SslContextFactory contextFactory = new SslContextFactory();
+        final SslContextFactory.Server contextFactory = new SslContextFactory.Server();
 
         // if needClientAuth is false then set want to true so we can optionally use certs
         if (properties.getNeedClientAuth()) {
diff --git a/nifi-registry-core/nifi-registry-web-api/pom.xml b/nifi-registry-core/nifi-registry-web-api/pom.xml
index df6090f..b165478 100644
--- a/nifi-registry-core/nifi-registry-web-api/pom.xml
+++ b/nifi-registry-core/nifi-registry-web-api/pom.xml
@@ -429,5 +429,11 @@
             <version>2.2.2</version>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>jetty-util</artifactId>
+            <version>${jetty.version}</version>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 </project>
diff --git a/nifi-registry-core/nifi-registry-web-api/src/test/java/org/apache/nifi/registry/web/JettyITServerCustomizer.java b/nifi-registry-core/nifi-registry-web-api/src/test/java/org/apache/nifi/registry/web/JettyITServerCustomizer.java
new file mode 100644
index 0000000..c0ff5b1
--- /dev/null
+++ b/nifi-registry-core/nifi-registry-web-api/src/test/java/org/apache/nifi/registry/web/JettyITServerCustomizer.java
@@ -0,0 +1,132 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.registry.web;
+
+
+import org.apache.commons.lang3.StringUtils;
+import org.eclipse.jetty.server.HttpConfiguration;
+import org.eclipse.jetty.server.HttpConnectionFactory;
+import org.eclipse.jetty.server.SecureRequestCustomizer;
+import org.eclipse.jetty.server.ServerConnector;
+import org.eclipse.jetty.server.SslConnectionFactory;
+import org.eclipse.jetty.util.ssl.SslContextFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.web.ServerProperties;
+import org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory;
+import org.springframework.boot.web.server.Ssl;
+import org.springframework.boot.web.server.WebServerFactoryCustomizer;
+import org.springframework.stereotype.Component;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * This customizer fixes integration tests. The customizer is the only way we can pass config from Spring Boot to Jetty.
+ * It sets the endpointIdentificationAlgorithm to null, which stops the Jetty server attempting to validate a hostname in the client certificate's SAN.
+ **/
+@Component
+public class JettyITServerCustomizer implements WebServerFactoryCustomizer<JettyServletWebServerFactory> {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(JettyITServerCustomizer.class);
+
+    @Autowired
+    private ServerProperties serverProperties;
+
+    private static final int HEADER_BUFFER_SIZE = 16 * 1024; // 16kb
+
+    @Override
+    public void customize(final JettyServletWebServerFactory factory) {
+        LOGGER.info("Customizing Jetty server for integration tests...");
+
+        factory.addServerCustomizers((server) -> {
+            final Ssl sslProperties = serverProperties.getSsl();
+            if (sslProperties != null) {
+                createSslContextFactory(sslProperties);
+                ServerConnector con = (ServerConnector) server.getConnectors()[0];
+                int existingConnectorPort = con.getLocalPort();
+
+                // create the http configuration
+                final HttpConfiguration httpConfiguration = new HttpConfiguration();
+                httpConfiguration.setRequestHeaderSize(HEADER_BUFFER_SIZE);
+                httpConfiguration.setResponseHeaderSize(HEADER_BUFFER_SIZE);
+
+                // add some secure config
+                final HttpConfiguration httpsConfiguration = new HttpConfiguration(httpConfiguration);
+                httpsConfiguration.setSecureScheme("https");
+                httpsConfiguration.setSecurePort(existingConnectorPort);
+                httpsConfiguration.addCustomizer(new SecureRequestCustomizer());
+
+                // build the connector with the endpoint identification algorithm set to null
+                final ServerConnector httpsConnector = new ServerConnector(server,
+                        new SslConnectionFactory(createSslContextFactory(sslProperties), "http/1.1"),
+                        new HttpConnectionFactory(httpsConfiguration));
+                server.removeConnector(con);
+                server.addConnector(httpsConnector);
+            }
+        });
+
+        LOGGER.info("JettyServer is customized");
+    }
+
+    private SslContextFactory createSslContextFactory(Ssl properties) {
+        // Calling SslContextFactory.Server() calls setEndpointIdentificationAlgorithm(null).
+        // This ensures that Jetty server does not attempt to validate a hostname in the client certificate's SAN.
+        final SslContextFactory.Server contextFactory = new SslContextFactory.Server();
+
+        // if needClientAuth is false then set want to true so we can optionally use certs
+        if(properties.getClientAuth() == Ssl.ClientAuth.NEED) {
+            LOGGER.info("Setting Jetty's SSLContextFactory needClientAuth to true");
+            contextFactory.setNeedClientAuth(true);
+        } else {
+            LOGGER.info("Setting Jetty's SSLContextFactory wantClientAuth to true");
+            contextFactory.setWantClientAuth(true);
+        }
+
+        /* below code sets JSSE system properties when values are provided */
+        // keystore properties
+        if (StringUtils.isNotBlank(properties.getKeyStore())) {
+            contextFactory.setKeyStorePath(properties.getKeyStore());
+        }
+        if (StringUtils.isNotBlank(properties.getKeyStoreType())) {
+            contextFactory.setKeyStoreType(properties.getKeyStoreType());
+        }
+        final String keystorePassword = properties.getKeyStorePassword();
+        final String keyPassword = properties.getKeyPassword();
+        if (StringUtils.isNotBlank(keystorePassword)) {
+            // if no key password was provided, then assume the keystore password is the same as the key password.
+            final String defaultKeyPassword = (StringUtils.isBlank(keyPassword)) ? keystorePassword : keyPassword;
+            contextFactory.setKeyManagerPassword(keystorePassword);
+            contextFactory.setKeyStorePassword(defaultKeyPassword);
+        } else if (StringUtils.isNotBlank(keyPassword)) {
+            // since no keystore password was provided, there will be no keystore integrity check
+            contextFactory.setKeyStorePassword(keyPassword);
+        }
+
+        // truststore properties
+        if (StringUtils.isNotBlank(properties.getTrustStore())) {
+            contextFactory.setTrustStorePath(properties.getTrustStore());
+        }
+        if (StringUtils.isNotBlank(properties.getTrustStoreType())) {
+            contextFactory.setTrustStoreType(properties.getTrustStoreType());
+        }
+        if (StringUtils.isNotBlank(properties.getTrustStorePassword())) {
+            contextFactory.setTrustStorePassword(properties.getTrustStorePassword());
+        }
+
+        return contextFactory;
+    }
+
+}
diff --git a/pom.xml b/pom.xml
index 0628184..69d1ed6 100644
--- a/pom.xml
+++ b/pom.xml
@@ -91,7 +91,7 @@
         <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
         <inceptionYear>2017</inceptionYear>
         <org.slf4j.version>1.7.12</org.slf4j.version>
-        <jetty.version>9.4.11.v20180605</jetty.version>
+        <jetty.version>9.4.19.v20190610</jetty.version>
         <jax.rs.api.version>2.1</jax.rs.api.version>
         <jersey.version>2.27</jersey.version>
         <jackson.version>2.9.8</jackson.version>