You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by al...@apache.org on 2020/06/22 19:20:53 UTC

[nifi] branch master updated: NIFI-7558 Fixed CatchAllFilter init logic by calling super.init(). Renamed legacy terms. Updated documentation.

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

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


The following commit(s) were added to refs/heads/master by this push:
     new 94c98c0  NIFI-7558 Fixed CatchAllFilter init logic by calling super.init(). Renamed legacy terms. Updated documentation.
94c98c0 is described below

commit 94c98c019f6704bea92ec15c1a5aa71b42e521ab
Author: Andy LoPresto <al...@apache.org>
AuthorDate: Thu Jun 18 19:57:58 2020 -0700

    NIFI-7558 Fixed CatchAllFilter init logic by calling super.init().
    Renamed legacy terms.
    Updated documentation.
    
    This closes #4351.
    
    Signed-off-by: Mark Payne <ma...@hotmail.com>
---
 .../java/org/apache/nifi/util/NiFiProperties.java  |  20 +--
 .../nifi/web/filter/SanitizeContextPathFilter.java |  25 ++--
 .../java/org/apache/nifi/web/util/WebUtils.java    |  30 ++--
 .../filter/SanitizeContextPathFilterTest.groovy    | 152 +++++++++++++++++++++
 .../org/apache/nifi/web/util/WebUtilsTest.groovy   |  88 ++++++------
 .../src/main/asciidoc/administration-guide.adoc    |   6 +-
 .../StandardNiFiPropertiesGroovyTest.groovy        |  26 ++--
 .../apache/nifi/web/server/HostHeaderHandler.java  |  25 ++--
 .../org/apache/nifi/web/server/JettyServer.java    |   4 +-
 .../nifi-jetty/src/test/resources/logback-test.xml |   2 +
 .../apache/nifi/web/api/ApplicationResource.java   |  69 +++++-----
 .../nifi/web/api/ApplicationResourceTest.groovy    |  76 +++++------
 .../org/apache/nifi/web/filter/CatchAllFilter.java |   4 +-
 .../nifi/web/filter/CatchAllFilterTest.groovy      | 152 +++++++++++++++++++++
 14 files changed, 490 insertions(+), 189 deletions(-)

diff --git a/nifi-commons/nifi-properties/src/main/java/org/apache/nifi/util/NiFiProperties.java b/nifi-commons/nifi-properties/src/main/java/org/apache/nifi/util/NiFiProperties.java
index 0943c87..662f5d0 100644
--- a/nifi-commons/nifi-properties/src/main/java/org/apache/nifi/util/NiFiProperties.java
+++ b/nifi-commons/nifi-properties/src/main/java/org/apache/nifi/util/NiFiProperties.java
@@ -1559,23 +1559,23 @@ public abstract class NiFiProperties {
     }
 
     /**
-     * Returns the whitelisted proxy hostnames (and IP addresses) as a comma-delimited string.
+     * Returns the allowed proxy hostnames (and IP addresses) as a comma-delimited string.
      * The hosts have been normalized to the form {@code somehost.com}, {@code somehost.com:port}, or {@code 127.0.0.1}.
      * <p>
      * Note: Calling {@code NiFiProperties.getProperty(NiFiProperties.WEB_PROXY_HOST)} will not normalize the hosts.
      *
      * @return the hostname(s)
      */
-    public String getWhitelistedHosts() {
-        return StringUtils.join(getWhitelistedHostsAsList(), ",");
+    public String getAllowedHosts() {
+        return StringUtils.join(getAllowedHostsAsList(), ",");
     }
 
     /**
-     * Returns the whitelisted proxy hostnames (and IP addresses) as a List. The hosts have been normalized to the form {@code somehost.com}, {@code somehost.com:port}, or {@code 127.0.0.1}.
+     * Returns the allowed proxy hostnames (and IP addresses) as a List. The hosts have been normalized to the form {@code somehost.com}, {@code somehost.com:port}, or {@code 127.0.0.1}.
      *
      * @return the hostname(s)
      */
-    public List<String> getWhitelistedHostsAsList() {
+    public List<String> getAllowedHostsAsList() {
         String rawProperty = getProperty(WEB_PROXY_HOST, "");
         List<String> hosts = Arrays.asList(rawProperty.split(","));
         return hosts.stream()
@@ -1591,22 +1591,22 @@ public abstract class NiFiProperties {
     }
 
     /**
-     * Returns the whitelisted proxy context paths as a comma-delimited string. The paths have been normalized to the form {@code /some/context/path}.
+     * Returns the allowed proxy context paths as a comma-delimited string. The paths have been normalized to the form {@code /some/context/path}.
      * <p>
      * Note: Calling {@code NiFiProperties.getProperty(NiFiProperties.WEB_PROXY_CONTEXT_PATH)} will not normalize the paths.
      *
      * @return the path(s)
      */
-    public String getWhitelistedContextPaths() {
-        return StringUtils.join(getWhitelistedContextPathsAsList(), ",");
+    public String getAllowedContextPaths() {
+        return StringUtils.join(getAllowedContextPathsAsList(), ",");
     }
 
     /**
-     * Returns the whitelisted proxy context paths as a list of paths. The paths have been normalized to the form {@code /some/context/path}.
+     * Returns the allowed proxy context paths as a list of paths. The paths have been normalized to the form {@code /some/context/path}.
      *
      * @return the path(s)
      */
-    public List<String> getWhitelistedContextPathsAsList() {
+    public List<String> getAllowedContextPathsAsList() {
         String rawProperty = getProperty(WEB_PROXY_CONTEXT_PATH, "");
         List<String> contextPaths = Arrays.asList(rawProperty.split(","));
         return contextPaths.stream()
diff --git a/nifi-commons/nifi-web-utils/src/main/java/org/apache/nifi/web/filter/SanitizeContextPathFilter.java b/nifi-commons/nifi-web-utils/src/main/java/org/apache/nifi/web/filter/SanitizeContextPathFilter.java
index 00b98d2..075f72d 100644
--- a/nifi-commons/nifi-web-utils/src/main/java/org/apache/nifi/web/filter/SanitizeContextPathFilter.java
+++ b/nifi-commons/nifi-web-utils/src/main/java/org/apache/nifi/web/filter/SanitizeContextPathFilter.java
@@ -23,6 +23,7 @@ import javax.servlet.FilterConfig;
 import javax.servlet.ServletException;
 import javax.servlet.ServletRequest;
 import javax.servlet.ServletResponse;
+import org.apache.nifi.util.StringUtils;
 import org.apache.nifi.web.util.WebUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -32,16 +33,17 @@ import org.slf4j.LoggerFactory;
  */
 public class SanitizeContextPathFilter implements Filter {
     private static final Logger logger = LoggerFactory.getLogger(SanitizeContextPathFilter.class);
+    private static final String ALLOWED_CONTEXT_PATHS_PARAMETER_NAME = "allowedContextPaths";
 
-    private String whitelistedContextPaths = "";
-
+    private String allowedContextPaths = "";
 
     @Override
     public void init(FilterConfig filterConfig) throws ServletException {
-        String providedWhitelist = filterConfig.getServletContext().getInitParameter("whitelistedContextPaths");
-        logger.debug("SanitizeContextPathFilter received provided whitelisted context paths from NiFi properties: " + providedWhitelist);
-        if (providedWhitelist != null) {
-            whitelistedContextPaths = providedWhitelist;
+        String providedAllowedList = filterConfig.getServletContext().getInitParameter(ALLOWED_CONTEXT_PATHS_PARAMETER_NAME);
+
+        logger.debug("SanitizeContextPathFilter received provided allowed context paths from NiFi properties: " + providedAllowedList);
+        if (StringUtils.isNotBlank(providedAllowedList)) {
+            allowedContextPaths = providedAllowedList;
         }
     }
 
@@ -56,11 +58,12 @@ public class SanitizeContextPathFilter implements Filter {
 
     /**
      * Determines, sanitizes, and injects the {@code contextPath} attribute into the {@code request}. If not present, an empty string {@code ""} is injected.
+     *
      * @param request the request
      */
     protected void injectContextPathAttribute(ServletRequest request) {
         // Capture the provided context path headers and sanitize them before using in the response
-        String contextPath = WebUtils.sanitizeContextPath(request, whitelistedContextPaths, "");
+        String contextPath = WebUtils.sanitizeContextPath(request, allowedContextPaths, "");
         request.setAttribute("contextPath", contextPath);
 
         logger.debug("SanitizeContextPathFilter set contextPath: " + contextPath);
@@ -71,11 +74,11 @@ public class SanitizeContextPathFilter implements Filter {
     }
 
     /**
-     * Getter for whitelistedContextPaths. Cannot be package-private because of an issue where the package is scoped per classloader.
+     * Getter for allowed context paths. Cannot be package-private because of an issue where the package is scoped per classloader.
      *
-     * @return the whitelisted context path(s)
+     * @return the allowed context path(s)
      */
-    protected String getWhitelistedContextPaths() {
-        return whitelistedContextPaths;
+    protected String getAllowedContextPaths() {
+        return allowedContextPaths;
     }
 }
diff --git a/nifi-commons/nifi-web-utils/src/main/java/org/apache/nifi/web/util/WebUtils.java b/nifi-commons/nifi-web-utils/src/main/java/org/apache/nifi/web/util/WebUtils.java
index fbf5c19..578206a 100644
--- a/nifi-commons/nifi-web-utils/src/main/java/org/apache/nifi/web/util/WebUtils.java
+++ b/nifi-commons/nifi-web-utils/src/main/java/org/apache/nifi/web/util/WebUtils.java
@@ -29,18 +29,18 @@ import javax.ws.rs.client.Client;
 import javax.ws.rs.client.ClientBuilder;
 import javax.ws.rs.core.UriBuilderException;
 import org.apache.commons.lang3.StringUtils;
+import org.apache.http.conn.ssl.DefaultHostnameVerifier;
 import org.glassfish.jersey.client.ClientConfig;
 import org.glassfish.jersey.jackson.internal.jackson.jaxrs.json.JacksonJaxbJsonProvider;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.apache.http.conn.ssl.DefaultHostnameVerifier;
 
 /**
  * Common utilities related to web development.
  */
 public final class WebUtils {
 
-    private static Logger logger = LoggerFactory.getLogger(WebUtils.class);
+    private static final Logger logger = LoggerFactory.getLogger(WebUtils.class);
 
     final static ReadWriteLock lock = new ReentrantReadWriteLock();
 
@@ -107,15 +107,15 @@ public final class WebUtils {
     }
 
     /**
-     * This method will check the provided context path headers against a whitelist (provided in nifi.properties) and throw an exception if the requested context path is not registered.
+     * This method will check the provided context path headers against an allow list (provided in nifi.properties) and throw an exception if the requested context path is not registered.
      *
      * @param uri                     the request URI
      * @param request                 the HTTP request
-     * @param whitelistedContextPaths comma-separated list of valid context paths
+     * @param allowedContextPaths     comma-separated list of valid context paths
      * @return the resource path
      * @throws UriBuilderException if the requested context path is not registered (header poisoning)
      */
-    public static String getResourcePath(URI uri, HttpServletRequest request, String whitelistedContextPaths) throws UriBuilderException {
+    public static String getResourcePath(URI uri, HttpServletRequest request, String allowedContextPaths) throws UriBuilderException {
         String resourcePath = uri.getPath();
 
         // Determine and normalize the context path
@@ -124,7 +124,7 @@ public final class WebUtils {
 
         // If present, check it and prepend to the resource path
         if (StringUtils.isNotBlank(determinedContextPath)) {
-            verifyContextPath(whitelistedContextPaths, determinedContextPath);
+            verifyContextPath(allowedContextPaths, determinedContextPath);
 
             // Determine the complete resource path
             resourcePath = determinedContextPath + resourcePath;
@@ -134,22 +134,22 @@ public final class WebUtils {
     }
 
     /**
-     * Throws an exception if the provided context path is not in the whitelisted context paths list.
+     * Throws an exception if the provided context path is not in the allowed context paths list.
      *
-     * @param whitelistedContextPaths a comma-delimited list of valid context paths
+     * @param allowedContextPaths a comma-delimited list of valid context paths
      * @param determinedContextPath   the normalized context path from a header
      * @throws UriBuilderException if the context path is not safe
      */
-    public static void verifyContextPath(String whitelistedContextPaths, String determinedContextPath) throws UriBuilderException {
+    public static void verifyContextPath(String allowedContextPaths, String determinedContextPath) throws UriBuilderException {
         // If blank, ignore
         if (StringUtils.isBlank(determinedContextPath)) {
             return;
         }
 
-        // Check it against the whitelist
-        List<String> individualContextPaths = Arrays.asList(StringUtils.split(whitelistedContextPaths, ","));
+        // Check it against the allowed list
+        List<String> individualContextPaths = Arrays.asList(StringUtils.split(allowedContextPaths, ","));
         if (!individualContextPaths.contains(determinedContextPath)) {
-            final String msg = "The provided context path [" + determinedContextPath + "] was not whitelisted [" + whitelistedContextPaths + "]";
+            final String msg = "The provided context path [" + determinedContextPath + "] was not registered as allowed [" + allowedContextPaths + "]";
             logger.error(msg);
             throw new UriBuilderException(msg);
         }
@@ -184,15 +184,17 @@ public final class WebUtils {
      * If no headers are present specifying this value, it is an empty string.
      *
      * @param request the HTTP request
+     * @param allowedContextPaths the comma-separated list of allowed context paths
+     * @param jspDisplayName the display name of the resource for log messages
      * @return the context path safe to be printed to the page
      */
-    public static String sanitizeContextPath(ServletRequest request, String whitelistedContextPaths, String jspDisplayName) {
+    public static String sanitizeContextPath(ServletRequest request, String allowedContextPaths, String jspDisplayName) {
         if (StringUtils.isBlank(jspDisplayName)) {
             jspDisplayName = "JSP page";
         }
         String contextPath = normalizeContextPath(determineContextPath((HttpServletRequest) request));
         try {
-            verifyContextPath(whitelistedContextPaths, contextPath);
+            verifyContextPath(allowedContextPaths, contextPath);
             return contextPath;
         } catch (UriBuilderException e) {
             logger.error("Error determining context path on " + jspDisplayName + ": " + e.getMessage());
diff --git a/nifi-commons/nifi-web-utils/src/test/groovy/org/apache/nifi/web/filter/SanitizeContextPathFilterTest.groovy b/nifi-commons/nifi-web-utils/src/test/groovy/org/apache/nifi/web/filter/SanitizeContextPathFilterTest.groovy
new file mode 100644
index 0000000..6f5949f
--- /dev/null
+++ b/nifi-commons/nifi-web-utils/src/test/groovy/org/apache/nifi/web/filter/SanitizeContextPathFilterTest.groovy
@@ -0,0 +1,152 @@
+/*
+ * 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.web.filter
+
+import org.bouncycastle.jce.provider.BouncyCastleProvider
+import org.junit.After
+import org.junit.Before
+import org.junit.BeforeClass
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+import org.slf4j.Logger
+import org.slf4j.LoggerFactory
+
+import javax.servlet.FilterConfig
+import javax.servlet.ServletContext
+import javax.servlet.http.HttpServletRequest
+import java.security.Security
+
+@RunWith(JUnit4.class)
+class SanitizeContextPathFilterTest extends GroovyTestCase {
+    private static final Logger logger = LoggerFactory.getLogger(SanitizeContextPathFilterTest.class)
+
+    @BeforeClass
+    static void setUpOnce() throws Exception {
+        Security.addProvider(new BouncyCastleProvider())
+
+        logger.metaClass.methodMissing = { String name, args ->
+            logger.info("[${name?.toUpperCase()}] ${(args as List).join(" ")}")
+        }
+    }
+
+    @Before
+    void setUp() throws Exception {
+
+    }
+
+    @After
+    void tearDown() throws Exception {
+
+    }
+
+    private static String getValue(String parameterName, Map<String, String> params = [:]) {
+        params.containsKey(parameterName) ? params[parameterName] : ""
+    }
+
+    @Test
+    void testInitShouldExtractAllowedContextPaths() {
+        // Arrange
+        def EXPECTED_ALLOWED_CONTEXT_PATHS = ["/path1", "/path2"].join(", ")
+        def parameters = [allowedContextPaths: EXPECTED_ALLOWED_CONTEXT_PATHS]
+        FilterConfig mockFilterConfig = [
+                getInitParameter : { String parameterName -> getValue(parameterName, parameters) },
+                getServletContext: { ->
+                    [getInitParameter: { String parameterName -> return getValue(parameterName, parameters) }] as ServletContext
+                }] as FilterConfig
+
+        SanitizeContextPathFilter scpf = new SanitizeContextPathFilter()
+
+        // Act
+        scpf.init(mockFilterConfig)
+        logger.info("Allowed context paths: ${scpf.getAllowedContextPaths()}")
+
+        // Assert
+        assert scpf.getAllowedContextPaths() == EXPECTED_ALLOWED_CONTEXT_PATHS
+    }
+
+    @Test
+    void testInitShouldHandleBlankAllowedContextPaths() {
+        // Arrange
+        def EXPECTED_ALLOWED_CONTEXT_PATHS = ""
+        FilterConfig mockFilterConfig = [
+                getInitParameter : { String parameterName -> "" },
+                getServletContext: { ->
+                    [getInitParameter: { String parameterName -> "" }] as ServletContext
+                }] as FilterConfig
+
+        SanitizeContextPathFilter scpf = new SanitizeContextPathFilter()
+
+        // Act
+        scpf.init(mockFilterConfig)
+        logger.info("Allowed context paths: ${scpf.getAllowedContextPaths()}")
+
+        // Assert
+        assert scpf.getAllowedContextPaths() == EXPECTED_ALLOWED_CONTEXT_PATHS
+    }
+
+    @Test
+    void testShouldInjectContextPathAttribute() {
+        // Arrange
+        final String EXPECTED_ALLOWED_CONTEXT_PATHS = ["/path1", "/path2"].join(", ")
+        final String EXPECTED_FORWARD_PATH = "index.jsp"
+        final Map PARAMETERS = [
+                allowedContextPaths: EXPECTED_ALLOWED_CONTEXT_PATHS,
+                forwardPath        : EXPECTED_FORWARD_PATH
+        ]
+
+        final String EXPECTED_CONTEXT_PATH = "/path1"
+
+        // Mock collaborators
+        FilterConfig mockFilterConfig = [
+                getInitParameter : { String parameterName ->
+                    return getValue(parameterName, PARAMETERS)
+                },
+                getServletContext: { ->
+                    [getInitParameter: { String parameterName ->
+                        return getValue(parameterName, PARAMETERS)
+                    }] as ServletContext
+                }] as FilterConfig
+
+        // Local map to store request attributes
+        def requestAttributes = [:]
+
+        final Map HEADERS = [
+                "X-ProxyContextPath" : "path1",
+                "X-Forwarded-Context": "",
+                "X-Forwarded-Prefix" : ""]
+
+        HttpServletRequest mockRequest = [
+                getContextPath      : { -> EXPECTED_CONTEXT_PATH },
+                getHeader           : { String headerName -> getValue(headerName, HEADERS) },
+                setAttribute        : { String attr, String value ->
+                    requestAttributes[attr] = value
+                    logger.mock("Set request attribute ${attr} to ${value}")
+                },
+        ] as HttpServletRequest
+
+        SanitizeContextPathFilter scpf = new SanitizeContextPathFilter()
+        scpf.init(mockFilterConfig)
+        logger.info("Allowed context paths: ${scpf.getAllowedContextPaths()}")
+
+        // Act
+        scpf.injectContextPathAttribute(mockRequest)
+
+        // Assert
+        assert requestAttributes["contextPath"] == EXPECTED_CONTEXT_PATH
+    }
+}
diff --git a/nifi-commons/nifi-web-utils/src/test/groovy/org/apache/nifi/web/util/WebUtilsTest.groovy b/nifi-commons/nifi-web-utils/src/test/groovy/org/apache/nifi/web/util/WebUtilsTest.groovy
index 6b68457..5465c2c 100644
--- a/nifi-commons/nifi-web-utils/src/test/groovy/org/apache/nifi/web/util/WebUtilsTest.groovy
+++ b/nifi-commons/nifi-web-utils/src/test/groovy/org/apache/nifi/web/util/WebUtilsTest.groovy
@@ -16,6 +16,7 @@
  */
 package org.apache.nifi.web.util
 
+import org.apache.http.conn.ssl.DefaultHostnameVerifier
 import org.glassfish.jersey.client.ClientConfig
 import org.junit.After
 import org.junit.Before
@@ -26,18 +27,17 @@ import org.junit.runners.JUnit4
 import org.mockito.Mockito
 import org.slf4j.Logger
 import org.slf4j.LoggerFactory
-import org.apache.http.conn.ssl.DefaultHostnameVerifier
 import sun.security.tools.keytool.CertAndKeyGen
 import sun.security.x509.X500Name
+
+import javax.net.ssl.HostnameVerifier
+import javax.net.ssl.SSLContext
 import javax.net.ssl.SSLPeerUnverifiedException
 import javax.servlet.http.HttpServletRequest
-import javax.ws.rs.core.UriBuilderException
 import javax.ws.rs.client.Client
-import javax.net.ssl.SSLContext
-import javax.net.ssl.HostnameVerifier
+import javax.ws.rs.core.UriBuilderException
 import java.security.cert.X509Certificate
 
-
 @RunWith(JUnit4.class)
 class WebUtilsTest extends GroovyTestCase {
     private static final Logger logger = LoggerFactory.getLogger(WebUtilsTest.class)
@@ -46,7 +46,7 @@ class WebUtilsTest extends GroovyTestCase {
     static final String FC_HEADER = "X-Forwarded-Context"
     static final String FP_HEADER = "X-Forwarded-Prefix"
 
-    static final String WHITELISTED_PATH = "/some/context/path"
+    static final String ALLOWED_PATH = "/some/context/path"
     private static final String OCSP_REQUEST_CONTENT_TYPE = "application/ocsp-request"
 
     @BeforeClass
@@ -92,7 +92,7 @@ class WebUtilsTest extends GroovyTestCase {
     @Test
     void testShouldDetermineCorrectContextPathWhenPresent() throws Exception {
         // Arrange
-        final String CORRECT_CONTEXT_PATH = WHITELISTED_PATH
+        final String CORRECT_CONTEXT_PATH = ALLOWED_PATH
         final String WRONG_CONTEXT_PATH = "this/is/a/bad/path"
 
         // Variety of requests with different ordering of context paths (the correct one is always "some/context/path"
@@ -145,8 +145,8 @@ class WebUtilsTest extends GroovyTestCase {
     @Test
     void testShouldNormalizeContextPath() throws Exception {
         // Arrange
-        final String CORRECT_CONTEXT_PATH = WHITELISTED_PATH
-        final String TRIMMED_PATH = WHITELISTED_PATH[1..-1] // Trims leading /
+        final String CORRECT_CONTEXT_PATH = ALLOWED_PATH
+        final String TRIMMED_PATH = ALLOWED_PATH[1..-1] // Trims leading /
 
         // Variety of different context paths (the correct one is always "/some/context/path")
         List<String> contextPaths = ["/$TRIMMED_PATH", "/" + TRIMMED_PATH, TRIMMED_PATH, TRIMMED_PATH + "/"]
@@ -162,9 +162,9 @@ class WebUtilsTest extends GroovyTestCase {
     }
 
     @Test
-    void testGetResourcePathShouldBlockContextPathHeaderIfNotInWhitelist() throws Exception {
+    void testGetResourcePathShouldBlockContextPathHeaderIfNotInAllowList() throws Exception {
         // Arrange
-        logger.info("Whitelisted path(s): ")
+        logger.info("Allowed path(s): ")
 
         HttpServletRequest requestWithProxyHeader = mockRequest([proxy: "any/context/path"])
         HttpServletRequest requestWithProxyAndForwardHeader = mockRequest([proxy: "any/context/path", forward: "any/other/context/path"])
@@ -181,14 +181,14 @@ class WebUtilsTest extends GroovyTestCase {
 
             // Assert
             logger.expected(msg)
-            assert msg =~ "The provided context path \\[.*\\] was not whitelisted \\[\\]"
+            assert msg =~ "The provided context path \\[.*\\] was not registered as allowed \\[\\]"
         }
     }
 
     @Test
-    void testGetResourcePathShouldAllowContextPathHeaderIfInWhitelist() throws Exception {
+    void testGetResourcePathShouldAllowContextPathHeaderIfInAllowList() throws Exception {
         // Arrange
-        logger.info("Whitelisted path(s): ${WHITELISTED_PATH}")
+        logger.info("Allowed path(s): ${ALLOWED_PATH}")
 
         HttpServletRequest requestWithProxyHeader = mockRequest([proxy: "some/context/path"])
         HttpServletRequest requestWithForwardHeader = mockRequest([forward: "some/context/path"])
@@ -200,21 +200,21 @@ class WebUtilsTest extends GroovyTestCase {
 
         // Act
         requests.each { HttpServletRequest request ->
-            String generatedResourcePath = WebUtils.getResourcePath(new URI('https://nifi.apache.org/actualResource'), request, WHITELISTED_PATH)
+            String generatedResourcePath = WebUtils.getResourcePath(new URI('https://nifi.apache.org/actualResource'), request, ALLOWED_PATH)
             logger.info("Generated Resource Path: ${generatedResourcePath}")
 
             // Assert
-            assert generatedResourcePath == "${WHITELISTED_PATH}/actualResource"
+            assert generatedResourcePath == "${ALLOWED_PATH}/actualResource"
         }
     }
 
     @Test
-    void testGetResourcePathShouldAllowContextPathHeaderIfElementInMultipleWhitelist() throws Exception {
+    void testGetResourcePathShouldAllowContextPathHeaderIfElementInMultipleAllowLists() throws Exception {
         // Arrange
-        String multipleWhitelistedPaths = [WHITELISTED_PATH, "/another/path", "/a/third/path", "/a/prefix/path"].join(",")
-        logger.info("Whitelisted path(s): ${multipleWhitelistedPaths}")
+        String multipleAllowedPaths = [ALLOWED_PATH, "/another/path", "/a/third/path", "/a/prefix/path"].join(",")
+        logger.info("Allowed path(s): ${multipleAllowedPaths}")
 
-        final List<String> VALID_RESOURCE_PATHS = multipleWhitelistedPaths.split(",").collect { "$it/actualResource" }
+        final List<String> VALID_RESOURCE_PATHS = multipleAllowedPaths.split(",").collect { "$it/actualResource" }
 
         HttpServletRequest requestWithProxyHeader = mockRequest([proxy: "some/context/path"])
         HttpServletRequest requestWithForwardHeader = mockRequest([forward: "another/path"])
@@ -227,7 +227,7 @@ class WebUtilsTest extends GroovyTestCase {
 
         // Act
         requests.each { HttpServletRequest request ->
-            String generatedResourcePath = WebUtils.getResourcePath(new URI('https://nifi.apache.org/actualResource'), request, multipleWhitelistedPaths)
+            String generatedResourcePath = WebUtils.getResourcePath(new URI('https://nifi.apache.org/actualResource'), request, multipleAllowedPaths)
             logger.info("Generated Resource Path: ${generatedResourcePath}")
 
             // Assert
@@ -236,14 +236,14 @@ class WebUtilsTest extends GroovyTestCase {
     }
 
     @Test
-    void testVerifyContextPathShouldAllowContextPathHeaderIfInWhitelist() throws Exception {
+    void testVerifyContextPathShouldAllowContextPathHeaderIfInAllowList() throws Exception {
         // Arrange
-        logger.info("Whitelisted path(s): ${WHITELISTED_PATH}")
-        String contextPath = WHITELISTED_PATH
+        logger.info("Allowed path(s): ${ALLOWED_PATH}")
+        String contextPath = ALLOWED_PATH
 
         // Act
-        logger.info("Testing [${contextPath}] against ${WHITELISTED_PATH}")
-        WebUtils.verifyContextPath(WHITELISTED_PATH, contextPath)
+        logger.info("Testing [${contextPath}] against ${ALLOWED_PATH}")
+        WebUtils.verifyContextPath(ALLOWED_PATH, contextPath)
         logger.info("Verified [${contextPath}]")
 
         // Assert
@@ -251,15 +251,15 @@ class WebUtilsTest extends GroovyTestCase {
     }
 
     @Test
-    void testVerifyContextPathShouldAllowContextPathHeaderIfInMultipleWhitelist() throws Exception {
+    void testVerifyContextPathShouldAllowContextPathHeaderIfInMultipleAllowLists() throws Exception {
         // Arrange
-        String multipleWhitelist = [WHITELISTED_PATH, WebUtils.normalizeContextPath(WHITELISTED_PATH.reverse())].join(",")
-        logger.info("Whitelisted path(s): ${multipleWhitelist}")
-        String contextPath = WHITELISTED_PATH
+        String multipleAllowLists = [ALLOWED_PATH, WebUtils.normalizeContextPath(ALLOWED_PATH.reverse())].join(",")
+        logger.info("Allowed path(s): ${multipleAllowLists}")
+        String contextPath = ALLOWED_PATH
 
         // Act
-        logger.info("Testing [${contextPath}] against ${multipleWhitelist}")
-        WebUtils.verifyContextPath(multipleWhitelist, contextPath)
+        logger.info("Testing [${contextPath}] against ${multipleAllowLists}")
+        WebUtils.verifyContextPath(multipleAllowLists, contextPath)
         logger.info("Verified [${contextPath}]")
 
         // Assert
@@ -269,14 +269,14 @@ class WebUtilsTest extends GroovyTestCase {
     @Test
     void testVerifyContextPathShouldAllowContextPathHeaderIfBlank() throws Exception {
         // Arrange
-        logger.info("Whitelisted path(s): ${WHITELISTED_PATH}")
+        logger.info("Allowed path(s): ${ALLOWED_PATH}")
 
         def emptyContextPaths = ["", "  ", "\t", null]
 
         // Act
         emptyContextPaths.each { String contextPath ->
-            logger.info("Testing [${contextPath}] against ${WHITELISTED_PATH}")
-            WebUtils.verifyContextPath(WHITELISTED_PATH, contextPath)
+            logger.info("Testing [${contextPath}] against ${ALLOWED_PATH}")
+            WebUtils.verifyContextPath(ALLOWED_PATH, contextPath)
             logger.info("Verified [${contextPath}]")
 
             // Assert
@@ -287,27 +287,26 @@ class WebUtilsTest extends GroovyTestCase {
     @Test
     void testVerifyContextPathShouldBlockContextPathHeaderIfNotAllowed() throws Exception {
         // Arrange
-        logger.info("Whitelisted path(s): ${WHITELISTED_PATH}")
+        logger.info("Allowed path(s): ${ALLOWED_PATH}")
 
         def invalidContextPaths = ["/other/path", "somesite.com", "/../trying/to/escape"]
 
         // Act
         invalidContextPaths.each { String contextPath ->
-            logger.info("Testing [${contextPath}] against ${WHITELISTED_PATH}")
+            logger.info("Testing [${contextPath}] against ${ALLOWED_PATH}")
             def msg = shouldFail(UriBuilderException) {
-                WebUtils.verifyContextPath(WHITELISTED_PATH, contextPath)
+                WebUtils.verifyContextPath(ALLOWED_PATH, contextPath)
                 logger.info("Verified [${contextPath}]")
             }
 
             // Assert
             logger.expected(msg)
-            assert msg =~ " was not whitelisted "
+            assert msg =~ " was not registered as allowed "
         }
     }
 
     @Test
     void testHostnameVerifierType() {
-
         // Arrange
         SSLContext sslContext = Mockito.mock(SSLContext.class)
         final ClientConfig clientConfig = new ClientConfig()
@@ -322,7 +321,6 @@ class WebUtilsTest extends GroovyTestCase {
 
     @Test
     void testHostnameVerifierWildcard() {
-
         // Arrange
         final String EXPECTED_DN = "CN=*.apache.com,OU=Security,O=Apache,ST=CA,C=US"
         final String hostname = "nifi.apache.com"
@@ -340,7 +338,6 @@ class WebUtilsTest extends GroovyTestCase {
 
     @Test
     void testHostnameVerifierDNWildcardFourthLevelDomain() {
-
         // Arrange
         final String EXPECTED_DN = "CN=*.nifi.apache.org,OU=Security,O=Apache,ST=CA,C=US"
         final String clientHostname = "client.nifi.apache.org"
@@ -361,7 +358,6 @@ class WebUtilsTest extends GroovyTestCase {
 
     @Test(expected = SSLPeerUnverifiedException)
     void testHostnameVerifierDomainLevelMismatch() {
-
         // Arrange
         final String EXPECTED_DN = "CN=*.nifi.apache.org,OU=Security,O=Apache,ST=CA,C=US"
         final String hostname = "nifi.apache.org"
@@ -379,7 +375,6 @@ class WebUtilsTest extends GroovyTestCase {
 
     @Test(expected = SSLPeerUnverifiedException)
     void testHostnameVerifierEmptyHostname() {
-
         // Arrange
         final String EXPECTED_DN = "CN=nifi.apache.org,OU=Security,O=Apache,ST=CA,C=US"
         final String hostname = ""
@@ -397,7 +392,6 @@ class WebUtilsTest extends GroovyTestCase {
 
     @Test(expected = SSLPeerUnverifiedException)
     void testHostnameVerifierDifferentSubdomain() {
-
         // Arrange
         final String EXPECTED_DN = "CN=nifi.apache.org,OU=Security,O=Apache,ST=CA,C=US"
         final String hostname = "egg.apache.org"
@@ -415,7 +409,6 @@ class WebUtilsTest extends GroovyTestCase {
 
     @Test(expected = SSLPeerUnverifiedException)
     void testHostnameVerifierDifferentTLD() {
-
         // Arrange
         final String EXPECTED_DN = "CN=nifi.apache.org,OU=Security,O=Apache,ST=CA,C=US"
         final String hostname = "nifi.apache.com"
@@ -433,7 +426,6 @@ class WebUtilsTest extends GroovyTestCase {
 
     @Test
     void testHostnameVerifierWildcardTLD() {
-
         // Arrange
         final String EXPECTED_DN = "CN=nifi.apache.*,OU=Security,O=Apache,ST=CA,C=US"
         final String comTLDhostname = "nifi.apache.com"
@@ -453,7 +445,6 @@ class WebUtilsTest extends GroovyTestCase {
 
     @Test
     void testHostnameVerifierWildcardDomain() {
-
         // Arrange
         final String EXPECTED_DN = "CN=nifi.*.com,OU=Security,O=Apache,ST=CA,C=US"
         final String hostname = "nifi.apache.com"
@@ -474,7 +465,6 @@ class WebUtilsTest extends GroovyTestCase {
          CertAndKeyGen certGenerator = new CertAndKeyGen("RSA", "SHA256WithRSA", null)
          certGenerator.generate(2048)
 
-
          long validityPeriod = (long) 365 * 24 * 60 * 60 // 1 YEAR
          X509Certificate cert = certGenerator.getSelfCertificate(new X500Name(DN), validityPeriod)
          return cert
diff --git a/nifi-docs/src/main/asciidoc/administration-guide.adoc b/nifi-docs/src/main/asciidoc/administration-guide.adoc
index a3864f0..b2653d2 100644
--- a/nifi-docs/src/main/asciidoc/administration-guide.adoc
+++ b/nifi-docs/src/main/asciidoc/administration-guide.adoc
@@ -2368,9 +2368,9 @@ host[:port] the expected values need to be configured. This may be required when
 separated list in _nifi.properties_ using the `nifi.web.proxy.host` property (e.g. `localhost:18443, proxyhost:443`). IPv6 addresses are accepted. Please refer to
 RFC 5952 Sections link:https://tools.ietf.org/html/rfc5952#section-4[4] and link:https://tools.ietf.org/html/rfc5952#section-6[6] for additional details.
 
-** NiFi will only accept HTTP requests with a X-ProxyContextPath, X-Forwarded-Context, or X-Forwarded-Prefix header if the value is whitelisted in the `nifi.web.proxy.context.path` property in
+** NiFi will only accept HTTP requests with a X-ProxyContextPath, X-Forwarded-Context, or X-Forwarded-Prefix header if the value is allowed in the `nifi.web.proxy.context.path` property in
 _nifi.properties_. This property accepts a comma separated list of expected values. In the event an incoming request has an X-ProxyContextPath, X-Forwarded-Context, or X-Forwarded-Prefix header value that is not
-present in the whitelist, the "An unexpected error has occurred" page will be shown and an error will be written to the _nifi-app.log_.
+present in the allow list, the "An unexpected error has occurred" page will be shown and an error will be written to the _nifi-app.log_.
 
 * Additional configurations at both proxy server and NiFi cluster are required to make NiFi Site-to-Site work behind reverse proxies. See <<site_to_site_reverse_proxy_properties>> for details.
 
@@ -2396,7 +2396,7 @@ See <<kerberos_properties>> for complete documentation.
 === Notes
 
 * Kerberos is case-sensitive in many places and the error messages (or lack thereof) may not be sufficiently explanatory. Check the case sensitivity of the service principal in your configuration files. Convention is `HTTP/fully.qualified.domain@REALM`.
-* Browsers have varying levels of restriction when dealing with SPNEGO negotiations. Some will provide the local Kerberos ticket to any domain that requests it, while others whitelist the trusted domains. See link:http://docs.spring.io/autorepo/docs/spring-security-kerberos/1.0.2.BUILD-SNAPSHOT/reference/htmlsingle/#browserspnegoconfig[Spring Security Kerberos - Reference Documentation: Appendix E. Configure browsers for SPNEGO Negotiation^] for common browsers.
+* Browsers have varying levels of restriction when dealing with SPNEGO negotiations. Some will provide the local Kerberos ticket to any domain that requests it, while others explicitly specify the trusted domains in advance via an allow list. See link:http://docs.spring.io/autorepo/docs/spring-security-kerberos/1.0.2.BUILD-SNAPSHOT/reference/htmlsingle/#browserspnegoconfig[Spring Security Kerberos - Reference Documentation: Appendix E. Configure browsers for SPNEGO Negotiation^] for comm [...]
 * Some browsers (legacy IE) do not support recent encryption algorithms such as AES, and are restricted to legacy algorithms (DES). This should be noted when generating keytabs.
 * The KDC must be configured and a service principal defined for NiFi and a keytab exported. Comprehensive instructions for Kerberos server configuration and administration are beyond the scope of this document (see link:http://web.mit.edu/kerberos/krb5-current/doc/admin/index.html[MIT Kerberos Admin Guide^]), but an example is below:
 
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-properties-loader/src/test/groovy/org/apache/nifi/properties/StandardNiFiPropertiesGroovyTest.groovy b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-properties-loader/src/test/groovy/org/apache/nifi/properties/StandardNiFiPropertiesGroovyTest.groovy
index aaae1e9..a4412fa 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-properties-loader/src/test/groovy/org/apache/nifi/properties/StandardNiFiPropertiesGroovyTest.groovy
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-properties-loader/src/test/groovy/org/apache/nifi/properties/StandardNiFiPropertiesGroovyTest.groovy
@@ -728,7 +728,7 @@ class StandardNiFiPropertiesGroovyTest extends GroovyTestCase {
         logger.info("Created a NiFiProperties instance with raw context path property [${noLeadingSlash}]")
 
         // Act
-        String normalizedContextPath = props.getWhitelistedContextPaths()
+        String normalizedContextPath = props.getAllowedContextPaths()
         logger.info("Read from NiFiProperties instance: ${normalizedContextPath}")
 
         // Assert
@@ -744,7 +744,7 @@ class StandardNiFiPropertiesGroovyTest extends GroovyTestCase {
         logger.info("Created a NiFiProperties instance with raw context path property [${leadingSlash}]")
 
         // Act
-        String normalizedContextPath = props.getWhitelistedContextPaths()
+        String normalizedContextPath = props.getAllowedContextPaths()
         logger.info("Read from NiFiProperties instance: ${normalizedContextPath}")
 
         // Assert
@@ -764,7 +764,7 @@ class StandardNiFiPropertiesGroovyTest extends GroovyTestCase {
         logger.info("Created a NiFiProperties instance with raw context path property [${noLeadingSlash}]")
 
         // Act
-        String normalizedContextPath = props.getWhitelistedContextPaths()
+        String normalizedContextPath = props.getAllowedContextPaths()
         logger.info("Read from NiFiProperties instance: ${normalizedContextPath}")
 
         // Assert
@@ -784,7 +784,7 @@ class StandardNiFiPropertiesGroovyTest extends GroovyTestCase {
         logger.info("Created a NiFiProperties instance with raw context path property [${leadingSlash}]")
 
         // Act
-        def normalizedContextPaths = props.getWhitelistedContextPathsAsList()
+        def normalizedContextPaths = props.getAllowedContextPathsAsList()
         logger.info("Read from NiFiProperties instance: ${normalizedContextPaths}")
 
         // Assert
@@ -805,7 +805,7 @@ class StandardNiFiPropertiesGroovyTest extends GroovyTestCase {
         logger.info("Created a NiFiProperties instance with raw context path property [${noLeadingSlash}]")
 
         // Act
-        def normalizedContextPaths = props.getWhitelistedContextPathsAsList()
+        def normalizedContextPaths = props.getAllowedContextPathsAsList()
         logger.info("Read from NiFiProperties instance: ${normalizedContextPaths}")
 
         // Assert
@@ -822,7 +822,7 @@ class StandardNiFiPropertiesGroovyTest extends GroovyTestCase {
         logger.info("Created a NiFiProperties instance with raw context path property [${empty}]")
 
         // Act
-        String normalizedContextPath = props.getWhitelistedContextPaths()
+        String normalizedContextPath = props.getAllowedContextPaths()
         logger.info("Read from NiFiProperties instance: ${normalizedContextPath}")
 
         // Assert
@@ -838,7 +838,7 @@ class StandardNiFiPropertiesGroovyTest extends GroovyTestCase {
         logger.info("Created a NiFiProperties instance with raw proxy host property [${extraSpaceHostname}]")
 
         // Act
-        String normalizedHostname = props.getWhitelistedHosts()
+        String normalizedHostname = props.getAllowedHosts()
         logger.info("Read from NiFiProperties instance: ${normalizedHostname}")
 
         // Assert
@@ -855,7 +855,7 @@ class StandardNiFiPropertiesGroovyTest extends GroovyTestCase {
         logger.info("Created a NiFiProperties instance with raw proxy host property [${hostname}]")
 
         // Act
-        String normalizedHostname = props.getWhitelistedHosts()
+        String normalizedHostname = props.getAllowedHosts()
         logger.info("Read from NiFiProperties instance: ${normalizedHostname}")
 
         // Assert
@@ -876,7 +876,7 @@ class StandardNiFiPropertiesGroovyTest extends GroovyTestCase {
         logger.info("Created a NiFiProperties instance with raw proxy host property [${combinedHosts}]")
 
         // Act
-        String normalizedHostname = props.getWhitelistedHosts()
+        String normalizedHostname = props.getAllowedHosts()
         logger.info("Read from NiFiProperties instance: ${normalizedHostname}")
 
         // Assert
@@ -897,7 +897,7 @@ class StandardNiFiPropertiesGroovyTest extends GroovyTestCase {
         logger.info("Created a NiFiProperties instance with raw proxy host property [${normalHostname}]")
 
         // Act
-        def listOfHosts = props.getWhitelistedHostsAsList()
+        def listOfHosts = props.getAllowedHostsAsList()
         logger.info("Read from NiFiProperties instance: ${listOfHosts}")
 
         // Assert
@@ -919,7 +919,7 @@ class StandardNiFiPropertiesGroovyTest extends GroovyTestCase {
         logger.info("Created a NiFiProperties instance with raw proxy host property [${combinedHosts}]")
 
         // Act
-        def listOfHosts = props.getWhitelistedHostsAsList()
+        def listOfHosts = props.getAllowedHostsAsList()
         logger.info("Read from NiFiProperties instance: ${listOfHosts}")
 
         // Assert
@@ -936,7 +936,7 @@ class StandardNiFiPropertiesGroovyTest extends GroovyTestCase {
         logger.info("Created a NiFiProperties instance with raw proxy host property [${empty}]")
 
         // Act
-        String normalizedHost = props.getWhitelistedHosts()
+        String normalizedHost = props.getAllowedHosts()
         logger.info("Read from NiFiProperties instance: ${normalizedHost}")
 
         // Assert
@@ -952,7 +952,7 @@ class StandardNiFiPropertiesGroovyTest extends GroovyTestCase {
         logger.info("Created a NiFiProperties instance with raw proxy host property [${empty}]")
 
         // Act
-        def hosts = props.getWhitelistedHostsAsList()
+        def hosts = props.getAllowedHostsAsList()
         logger.info("Read from NiFiProperties instance: ${hosts}")
 
         // Assert
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/main/java/org/apache/nifi/web/server/HostHeaderHandler.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/main/java/org/apache/nifi/web/server/HostHeaderHandler.java
index 5ccf1e0..9a411fa 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/main/java/org/apache/nifi/web/server/HostHeaderHandler.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/main/java/org/apache/nifi/web/server/HostHeaderHandler.java
@@ -17,18 +17,6 @@
 package org.apache.nifi.web.server;
 
 import com.google.common.base.Strings;
-import org.apache.commons.text.StringEscapeUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.http.conn.util.InetAddressUtils;
-import org.apache.nifi.util.NiFiProperties;
-import org.eclipse.jetty.server.Request;
-import org.eclipse.jetty.server.handler.ScopedHandler;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.net.InetAddress;
@@ -41,6 +29,17 @@ import java.util.List;
 import java.util.Map;
 import java.util.Objects;
 import java.util.stream.Collectors;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.text.StringEscapeUtils;
+import org.apache.http.conn.util.InetAddressUtils;
+import org.apache.nifi.util.NiFiProperties;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.handler.ScopedHandler;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public class HostHeaderHandler extends ScopedHandler {
     private static final Logger logger = LoggerFactory.getLogger(HostHeaderHandler.class);
@@ -130,7 +129,7 @@ public class HostHeaderHandler extends ScopedHandler {
      */
     List<String> parseCustomHostnames(NiFiProperties niFiProperties) {
         // Load the custom hostnames from the properties
-        List<String> customHostnames = niFiProperties.getWhitelistedHostsAsList();
+        List<String> customHostnames = niFiProperties.getAllowedHostsAsList();
 
         /* Each IPv4 address and hostname may have the port associated, so duplicate the list and trim the port
         * (the port may be different from the port NiFi is running on if provided by a proxy, etc.) IPv6 addresses
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 b9b9c84..666fe00 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
@@ -274,7 +274,7 @@ public class JettyServer implements NiFiServer, ExtensionUiLoader {
         final WebAppContext webUiContext = loadWar(webUiWar, "/nifi", frameworkClassLoader);
         webUiContext.getInitParams().put("oidc-supported", String.valueOf(props.isOidcEnabled()));
         webUiContext.getInitParams().put("knox-supported", String.valueOf(props.isKnoxSsoEnabled()));
-        webUiContext.getInitParams().put("whitelistedContextPaths", props.getWhitelistedContextPaths());
+        webUiContext.getInitParams().put("allowedContextPaths", props.getAllowedContextPaths());
         webAppContextHandlers.addHandler(webUiContext);
 
         // load the web api app
@@ -299,7 +299,7 @@ public class JettyServer implements NiFiServer, ExtensionUiLoader {
 
         // load the web error app
         final WebAppContext webErrorContext = loadWar(webErrorWar, "/", frameworkClassLoader);
-        webErrorContext.getInitParams().put("whitelistedContextPaths", props.getWhitelistedContextPaths());
+        webErrorContext.getInitParams().put("allowedContextPaths", props.getAllowedContextPaths());
         webAppContextHandlers.addHandler(webErrorContext);
 
         // deploy the web apps
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/test/resources/logback-test.xml b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/test/resources/logback-test.xml
index 4e4a789..d62c209 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/test/resources/logback-test.xml
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/test/resources/logback-test.xml
@@ -31,6 +31,8 @@
 
     <logger name="org.apache.nifi" level="INFO"/>
     <logger name="org.apache.nifi.web.server" level="DEBUG"/>
+    <logger name="org.apache.nifi.web.util" level="DEBUG"/>
+    <logger name="org.apache.nifi.web.filter" level="DEBUG"/>
     <logger name="org.eclipse.jetty.server" level="DEBUG"/>
     <root level="INFO">
         <appender-ref ref="CONSOLE"/>
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ApplicationResource.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ApplicationResource.java
index dcc34a1..196ba27 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ApplicationResource.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ApplicationResource.java
@@ -16,8 +16,40 @@
  */
 package org.apache.nifi.web.api;
 
+import static javax.ws.rs.core.Response.Status.NOT_FOUND;
+import static org.apache.commons.lang3.StringUtils.isEmpty;
+import static org.apache.nifi.remote.protocol.http.HttpHeaders.LOCATION_URI_INTENT_NAME;
+import static org.apache.nifi.remote.protocol.http.HttpHeaders.LOCATION_URI_INTENT_VALUE;
+
 import com.google.common.cache.Cache;
 import com.google.common.cache.CacheBuilder;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.nio.charset.StandardCharsets;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.UUID;
+import java.util.concurrent.TimeUnit;
+import java.util.function.BiFunction;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.ws.rs.core.CacheControl;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedHashMap;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.ResponseBuilder;
+import javax.ws.rs.core.UriBuilder;
+import javax.ws.rs.core.UriBuilderException;
+import javax.ws.rs.core.UriInfo;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.nifi.authorization.AuthorizableLookup;
 import org.apache.nifi.authorization.AuthorizeAccess;
@@ -60,39 +92,6 @@ import org.apache.nifi.web.util.WebUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import javax.ws.rs.core.CacheControl;
-import javax.ws.rs.core.Context;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.MultivaluedHashMap;
-import javax.ws.rs.core.MultivaluedMap;
-import javax.ws.rs.core.Response;
-import javax.ws.rs.core.Response.ResponseBuilder;
-import javax.ws.rs.core.UriBuilder;
-import javax.ws.rs.core.UriBuilderException;
-import javax.ws.rs.core.UriInfo;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.nio.charset.StandardCharsets;
-import java.util.Collections;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Optional;
-import java.util.Set;
-import java.util.TreeMap;
-import java.util.UUID;
-import java.util.concurrent.TimeUnit;
-import java.util.function.BiFunction;
-import java.util.function.Consumer;
-import java.util.function.Function;
-
-import static javax.ws.rs.core.Response.Status.NOT_FOUND;
-import static org.apache.commons.lang3.StringUtils.isEmpty;
-import static org.apache.nifi.remote.protocol.http.HttpHeaders.LOCATION_URI_INTENT_NAME;
-import static org.apache.nifi.remote.protocol.http.HttpHeaders.LOCATION_URI_INTENT_VALUE;
-
 /**
  * Base class for controllers.
  */
@@ -162,8 +161,8 @@ public abstract class ApplicationResource {
             final String port = determineProxiedPort(hostHeaderValue, portHeaderValue);
 
             // Catch header poisoning
-            String whitelistedContextPaths = properties.getWhitelistedContextPaths();
-            String resourcePath = WebUtils.getResourcePath(uri, httpServletRequest, whitelistedContextPaths);
+            String allowedContextPaths = properties.getAllowedContextPaths();
+            String resourcePath = WebUtils.getResourcePath(uri, httpServletRequest, allowedContextPaths);
 
             // determine the port uri
             int uriPort = uri.getPort();
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/groovy/org/apache/nifi/web/api/ApplicationResourceTest.groovy b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/groovy/org/apache/nifi/web/api/ApplicationResourceTest.groovy
index 00e888c..2d4b496 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/groovy/org/apache/nifi/web/api/ApplicationResourceTest.groovy
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/groovy/org/apache/nifi/web/api/ApplicationResourceTest.groovy
@@ -49,7 +49,7 @@ class ApplicationResourceTest extends GroovyTestCase {
     static final String FORWARDED_PREFIX_HTTP_HEADER = "X-Forwarded-Prefix"
 
     static final String PROXY_CONTEXT_PATH_PROP = NiFiProperties.WEB_PROXY_CONTEXT_PATH
-    static final String WHITELISTED_PATH = "/some/context/path"
+    static final String ALLOWED_PATH = "/some/context/path"
 
     @BeforeClass
     static void setUpOnce() throws Exception {
@@ -85,7 +85,7 @@ class ApplicationResourceTest extends GroovyTestCase {
         String headerValue = ""
         HttpServletRequest mockRequest = [getHeader: { String k ->
             if (proxyHeaders.contains(k)) {
-                headerValue = WHITELISTED_PATH
+                headerValue = ALLOWED_PATH
             } else if ([FORWARDED_PORT_HTTP_HEADER, PROXY_PORT_HTTP_HEADER].contains(k)) {
                 headerValue = "8081"
             } else if ([FORWARDED_PROTO_HTTP_HEADER, PROXY_SCHEME_HTTP_HEADER].contains(k)) {
@@ -115,10 +115,10 @@ class ApplicationResourceTest extends GroovyTestCase {
     }
 
     @Test
-    void testGenerateUriShouldBlockProxyContextPathHeaderIfNotInWhitelist() throws Exception {
+    void testGenerateUriShouldBlockProxyContextPathHeaderIfNotInAllowList() throws Exception {
         // Arrange
         ApplicationResource resource = buildApplicationResource()
-        logger.info("Whitelisted path(s): ")
+        logger.info("Allowed path(s): ")
 
         // Act
         def msg = shouldFail(UriBuilderException) {
@@ -128,15 +128,15 @@ class ApplicationResourceTest extends GroovyTestCase {
 
         // Assert
         logger.expected(msg)
-        assert msg =~ "The provided context path \\[.*\\] was not whitelisted \\[\\]"
+        assert msg =~ "The provided context path \\[.*\\] was not registered as allowed \\[\\]"
     }
 
     @Test
-    void testGenerateUriShouldAllowProxyContextPathHeaderIfInWhitelist() throws Exception {
+    void testGenerateUriShouldAllowProxyContextPathHeaderIfInAllowList() throws Exception {
         // Arrange
         ApplicationResource resource = buildApplicationResource()
-        logger.info("Whitelisted path(s): ${WHITELISTED_PATH}")
-        NiFiProperties niFiProperties = new StandardNiFiProperties([(PROXY_CONTEXT_PATH_PROP): WHITELISTED_PATH] as Properties)
+        logger.info("Allowed path(s): ${ALLOWED_PATH}")
+        NiFiProperties niFiProperties = new StandardNiFiProperties([(PROXY_CONTEXT_PATH_PROP): ALLOWED_PATH] as Properties)
         resource.properties = niFiProperties
 
         // Act
@@ -144,16 +144,16 @@ class ApplicationResourceTest extends GroovyTestCase {
         logger.info("Generated URI: ${generatedUri}")
 
         // Assert
-        assert generatedUri == "https://nifi.apache.org:8081${WHITELISTED_PATH}/actualResource"
+        assert generatedUri == "https://nifi.apache.org:8081${ALLOWED_PATH}/actualResource"
     }
 
     @Test
-    void testGenerateUriShouldAllowProxyContextPathHeaderIfElementInMultipleWhitelist() throws Exception {
+    void testGenerateUriShouldAllowProxyContextPathHeaderIfElementInMultipleAllowList() throws Exception {
         // Arrange
         ApplicationResource resource = buildApplicationResource()
-        String multipleWhitelistedPaths = [WHITELISTED_PATH, "another/path", "a/third/path"].join(",")
-        logger.info("Whitelisted path(s): ${multipleWhitelistedPaths}")
-        NiFiProperties niFiProperties = new StandardNiFiProperties([(PROXY_CONTEXT_PATH_PROP): multipleWhitelistedPaths] as Properties)
+        String multipleAllowedPaths = [ALLOWED_PATH, "another/path", "a/third/path"].join(",")
+        logger.info("Allowed path(s): ${multipleAllowedPaths}")
+        NiFiProperties niFiProperties = new StandardNiFiProperties([(PROXY_CONTEXT_PATH_PROP): multipleAllowedPaths] as Properties)
         resource.properties = niFiProperties
 
         // Act
@@ -161,14 +161,14 @@ class ApplicationResourceTest extends GroovyTestCase {
         logger.info("Generated URI: ${generatedUri}")
 
         // Assert
-        assert generatedUri == "https://nifi.apache.org:8081${WHITELISTED_PATH}/actualResource"
+        assert generatedUri == "https://nifi.apache.org:8081${ALLOWED_PATH}/actualResource"
     }
 
     @Test
-    void testGenerateUriShouldBlockForwardedContextHeaderIfNotInWhitelist() throws Exception {
+    void testGenerateUriShouldBlockForwardedContextHeaderIfNotInAllowList() throws Exception {
         // Arrange
         ApplicationResource resource = buildApplicationResource([FORWARDED_CONTEXT_HTTP_HEADER])
-        logger.info("Whitelisted path(s): ")
+        logger.info("Allowed path(s): ")
 
         // Act
         def msg = shouldFail(UriBuilderException) {
@@ -178,14 +178,14 @@ class ApplicationResourceTest extends GroovyTestCase {
 
         // Assert
         logger.expected(msg)
-        assert msg =~ "The provided context path \\[.*\\] was not whitelisted \\[\\]"
+        assert msg =~ "The provided context path \\[.*\\] was not registered as allowed \\[\\]"
     }
 
     @Test
-    void testGenerateUriShouldBlockForwardedPrefixHeaderIfNotInWhitelist() throws Exception {
+    void testGenerateUriShouldBlockForwardedPrefixHeaderIfNotInAllowList() throws Exception {
         // Arrange
         ApplicationResource resource = buildApplicationResource([FORWARDED_PREFIX_HTTP_HEADER])
-        logger.info("Whitelisted path(s): ")
+        logger.info("Allowed path(s): ")
 
         // Act
         def msg = shouldFail(UriBuilderException) {
@@ -195,15 +195,15 @@ class ApplicationResourceTest extends GroovyTestCase {
 
         // Assert
         logger.expected(msg)
-        assert msg =~ "The provided context path \\[.*\\] was not whitelisted \\[\\]"
+        assert msg =~ "The provided context path \\[.*\\] was not registered as allowed \\[\\]"
     }
 
     @Test
-    void testGenerateUriShouldAllowForwardedContextHeaderIfInWhitelist() throws Exception {
+    void testGenerateUriShouldAllowForwardedContextHeaderIfInAllowList() throws Exception {
         // Arrange
         ApplicationResource resource = buildApplicationResource([FORWARDED_CONTEXT_HTTP_HEADER])
-        logger.info("Whitelisted path(s): ${WHITELISTED_PATH}")
-        NiFiProperties niFiProperties = new StandardNiFiProperties([(PROXY_CONTEXT_PATH_PROP): WHITELISTED_PATH] as Properties)
+        logger.info("Allowed path(s): ${ALLOWED_PATH}")
+        NiFiProperties niFiProperties = new StandardNiFiProperties([(PROXY_CONTEXT_PATH_PROP): ALLOWED_PATH] as Properties)
         resource.properties = niFiProperties
 
         // Act
@@ -211,15 +211,15 @@ class ApplicationResourceTest extends GroovyTestCase {
         logger.info("Generated URI: ${generatedUri}")
 
         // Assert
-        assert generatedUri == "https://nifi.apache.org:8081${WHITELISTED_PATH}/actualResource"
+        assert generatedUri == "https://nifi.apache.org:8081${ALLOWED_PATH}/actualResource"
     }
 
     @Test
-    void testGenerateUriShouldAllowForwardedPrefixHeaderIfInWhitelist() throws Exception {
+    void testGenerateUriShouldAllowForwardedPrefixHeaderIfInAllowList() throws Exception {
         // Arrange
         ApplicationResource resource = buildApplicationResource([FORWARDED_PREFIX_HTTP_HEADER])
-        logger.info("Whitelisted path(s): ${WHITELISTED_PATH}")
-        NiFiProperties niFiProperties = new StandardNiFiProperties([(PROXY_CONTEXT_PATH_PROP): WHITELISTED_PATH] as Properties)
+        logger.info("Allowed path(s): ${ALLOWED_PATH}")
+        NiFiProperties niFiProperties = new StandardNiFiProperties([(PROXY_CONTEXT_PATH_PROP): ALLOWED_PATH] as Properties)
         resource.properties = niFiProperties
 
         // Act
@@ -227,16 +227,16 @@ class ApplicationResourceTest extends GroovyTestCase {
         logger.info("Generated URI: ${generatedUri}")
 
         // Assert
-        assert generatedUri == "https://nifi.apache.org:8081${WHITELISTED_PATH}/actualResource"
+        assert generatedUri == "https://nifi.apache.org:8081${ALLOWED_PATH}/actualResource"
     }
 
     @Test
-    void testGenerateUriShouldAllowForwardedContextHeaderIfElementInMultipleWhitelist() throws Exception {
+    void testGenerateUriShouldAllowForwardedContextHeaderIfElementInMultipleAllowList() throws Exception {
         // Arrange
         ApplicationResource resource = buildApplicationResource([FORWARDED_CONTEXT_HTTP_HEADER])
-        String multipleWhitelistedPaths = [WHITELISTED_PATH, "another/path", "a/third/path"].join(",")
-        logger.info("Whitelisted path(s): ${multipleWhitelistedPaths}")
-        NiFiProperties niFiProperties = new StandardNiFiProperties([(PROXY_CONTEXT_PATH_PROP): multipleWhitelistedPaths] as Properties)
+        String multipleAllowedPaths = [ALLOWED_PATH, "another/path", "a/third/path"].join(",")
+        logger.info("Allowed path(s): ${multipleAllowedPaths}")
+        NiFiProperties niFiProperties = new StandardNiFiProperties([(PROXY_CONTEXT_PATH_PROP): multipleAllowedPaths] as Properties)
         resource.properties = niFiProperties
 
         // Act
@@ -244,16 +244,16 @@ class ApplicationResourceTest extends GroovyTestCase {
         logger.info("Generated URI: ${generatedUri}")
 
         // Assert
-        assert generatedUri == "https://nifi.apache.org:8081${WHITELISTED_PATH}/actualResource"
+        assert generatedUri == "https://nifi.apache.org:8081${ALLOWED_PATH}/actualResource"
     }
 
     @Test
-    void testGenerateUriShouldAllowForwardedPrefixHeaderIfElementInMultipleWhitelist() throws Exception {
+    void testGenerateUriShouldAllowForwardedPrefixHeaderIfElementInMultipleAllowList() throws Exception {
         // Arrange
         ApplicationResource resource = buildApplicationResource([FORWARDED_PREFIX_HTTP_HEADER])
-        String multipleWhitelistedPaths = [WHITELISTED_PATH, "another/path", "a/third/path"].join(",")
-        logger.info("Whitelisted path(s): ${multipleWhitelistedPaths}")
-        NiFiProperties niFiProperties = new StandardNiFiProperties([(PROXY_CONTEXT_PATH_PROP): multipleWhitelistedPaths] as Properties)
+        String multipleAllowedPaths = [ALLOWED_PATH, "another/path", "a/third/path"].join(",")
+        logger.info("Allowed path(s): ${multipleAllowedPaths}")
+        NiFiProperties niFiProperties = new StandardNiFiProperties([(PROXY_CONTEXT_PATH_PROP): multipleAllowedPaths] as Properties)
         resource.properties = niFiProperties
 
         // Act
@@ -261,6 +261,6 @@ class ApplicationResourceTest extends GroovyTestCase {
         logger.info("Generated URI: ${generatedUri}")
 
         // Assert
-        assert generatedUri == "https://nifi.apache.org:8081${WHITELISTED_PATH}/actualResource"
+        assert generatedUri == "https://nifi.apache.org:8081${ALLOWED_PATH}/actualResource"
     }
 }
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-error/src/main/java/org/apache/nifi/web/filter/CatchAllFilter.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-error/src/main/java/org/apache/nifi/web/filter/CatchAllFilter.java
index fa94e64..4c60f7b 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-error/src/main/java/org/apache/nifi/web/filter/CatchAllFilter.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-error/src/main/java/org/apache/nifi/web/filter/CatchAllFilter.java
@@ -39,11 +39,13 @@ public class CatchAllFilter extends SanitizeContextPathFilter {
 
     @Override
     public void init(FilterConfig filterConfig) throws ServletException {
+        super.init(filterConfig);
+
         // TODO: Perform path validation (against what set of rules)?
         forwardPath = filterConfig.getInitParameter("forwardPath");
         displayPath = filterConfig.getInitParameter("displayPath");
 
-        logger.debug("CatchAllFilter  [" + displayPath + "] received provided whitelisted context paths from NiFi properties: " + getWhitelistedContextPaths());
+        logger.debug("CatchAllFilter [" + displayPath + "] received provided allowed context paths from NiFi properties: " + getAllowedContextPaths());
     }
 
     @Override
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-error/src/test/groovy/org/apache/nifi/web/filter/CatchAllFilterTest.groovy b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-error/src/test/groovy/org/apache/nifi/web/filter/CatchAllFilterTest.groovy
new file mode 100644
index 0000000..2d9f4e3
--- /dev/null
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-error/src/test/groovy/org/apache/nifi/web/filter/CatchAllFilterTest.groovy
@@ -0,0 +1,152 @@
+/*
+ * 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.web.filter
+
+
+import org.bouncycastle.jce.provider.BouncyCastleProvider
+import org.junit.After
+import org.junit.Before
+import org.junit.BeforeClass
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+import org.slf4j.Logger
+import org.slf4j.LoggerFactory
+
+import javax.servlet.FilterChain
+import javax.servlet.FilterConfig
+import javax.servlet.RequestDispatcher
+import javax.servlet.ServletContext
+import javax.servlet.ServletRequest
+import javax.servlet.ServletResponse
+import javax.servlet.http.HttpServletRequest
+import javax.servlet.http.HttpServletResponse
+import java.security.Security
+
+@RunWith(JUnit4.class)
+class CatchAllFilterTest extends GroovyTestCase {
+    private static final Logger logger = LoggerFactory.getLogger(CatchAllFilterTest.class)
+
+    @BeforeClass
+    static void setUpOnce() throws Exception {
+        Security.addProvider(new BouncyCastleProvider())
+
+        logger.metaClass.methodMissing = { String name, args ->
+            logger.info("[${name?.toUpperCase()}] ${(args as List).join(" ")}")
+        }
+    }
+
+    @Before
+    void setUp() throws Exception {
+
+    }
+
+    @After
+    void tearDown() throws Exception {
+
+    }
+
+    private static String getValue(String parameterName, Map<String, String> params = [:]) {
+        params.containsKey(parameterName) ? params[parameterName] : ""
+    }
+
+    @Test
+    void testInitShouldCallSuper() {
+        // Arrange
+        def EXPECTED_ALLOWED_CONTEXT_PATHS = ["/path1", "/path2"].join(", ")
+        def parameters = [allowedContextPaths: EXPECTED_ALLOWED_CONTEXT_PATHS]
+        FilterConfig mockFilterConfig = [
+                getInitParameter : { String parameterName ->
+                    return getValue(parameterName, parameters)
+                },
+                getServletContext: { ->
+                    [getInitParameter: { String parameterName ->
+                        return getValue(parameterName, parameters)
+                    }] as ServletContext
+                }] as FilterConfig
+
+        CatchAllFilter caf = new CatchAllFilter()
+
+        // Act
+        caf.init(mockFilterConfig)
+        logger.info("Allowed context paths: ${caf.getAllowedContextPaths()}")
+
+        // Assert
+        assert caf.getAllowedContextPaths() == EXPECTED_ALLOWED_CONTEXT_PATHS
+    }
+
+    @Test
+    void testShouldDoFilter() {
+        // Arrange
+        final String EXPECTED_ALLOWED_CONTEXT_PATHS = ["/path1", "/path2"].join(", ")
+        final String EXPECTED_FORWARD_PATH = "index.jsp"
+        final Map PARAMETERS = [
+                allowedContextPaths: EXPECTED_ALLOWED_CONTEXT_PATHS,
+                forwardPath        : EXPECTED_FORWARD_PATH
+        ]
+
+        final String EXPECTED_CONTEXT_PATH = ""
+
+        // Mock collaborators
+        FilterConfig mockFilterConfig = [
+                getInitParameter : { String parameterName ->
+                    return getValue(parameterName, PARAMETERS)
+                },
+                getServletContext: { ->
+                    [getInitParameter: { String parameterName ->
+                        return getValue(parameterName, PARAMETERS)
+                    }] as ServletContext
+                }] as FilterConfig
+
+        // Local map to store request attributes
+        def requestAttributes = [:]
+
+        // Local string to store resulting path
+        String forwardedRequestTo = ""
+
+        final Map HEADERS = [
+                "X-ProxyContextPath" : "",
+                "X-Forwarded-Context": "",
+                "X-Forwarded-Prefix" : ""]
+
+        HttpServletRequest mockRequest = [
+                getContextPath      : { -> EXPECTED_CONTEXT_PATH },
+                getHeader           : { String headerName -> getValue(headerName, HEADERS) },
+                setAttribute        : { String attr, String value ->
+                    requestAttributes[attr] = value
+                    logger.mock("Set request attribute ${attr} to ${value}")
+                },
+                getRequestDispatcher: { String path ->
+                    [forward: { ServletRequest request, ServletResponse response ->
+                        forwardedRequestTo = path
+                        logger.mock("Forwarded request to ${path}")
+                    }] as RequestDispatcher
+                }] as HttpServletRequest
+        HttpServletResponse mockResponse = [:] as HttpServletResponse
+        FilterChain mockFilterChain = [:] as FilterChain
+
+        CatchAllFilter caf = new CatchAllFilter()
+        caf.init(mockFilterConfig)
+        logger.info("Allowed context paths: ${caf.getAllowedContextPaths()}")
+
+        // Act
+        caf.doFilter(mockRequest, mockResponse, mockFilterChain)
+
+        // Assert
+        assert forwardedRequestTo == EXPECTED_FORWARD_PATH
+    }
+}