From 33da3463b681a00a1b72e2c3ee04e79696b2610a Mon Sep 17 00:00:00 2001 From: David Handermann Date: Tue, 30 Jul 2024 14:41:49 -0500 Subject: [PATCH] NIFI-13594 Added web-servlet-shared abstracted from web-utils (#9123) - Moved RequestUriBuilder from web-utils to web-servlet-shared - Refactored proxy header parsing from WebUtils to StandardRequestUriProvider - Renamed WebUtils to WebClientUtils This closes #9123 --- nifi-commons/nifi-web-servlet-shared/pom.xml | 32 ++ .../nifi/web/servlet/shared/ProxyHeader.java | 52 +++ .../servlet/shared}/RequestUriBuilder.java | 39 +- .../servlet/shared/RequestUriProvider.java | 34 ++ .../shared/StandardRequestUriProvider.java | 195 ++++++++++ .../shared}/RequestUriBuilderTest.java | 24 +- .../StandardRequestUriProviderTest.java | 349 ++++++++++++++++++ nifi-commons/nifi-web-utils/pom.xml | 13 - .../web/filter/SanitizeContextPathFilter.java | 84 ----- .../apache/nifi/web/util/WebClientUtils.java | 89 +++++ .../org/apache/nifi/web/util/WebUtils.java | 349 ------------------ .../filter/SanitizeContextPathFilterTest.java | 99 ----- .../apache/nifi/web/util/WebUtilsTest.java | 133 ------- nifi-commons/pom.xml | 1 + .../client/RestSchemaRegistryClient.java | 4 +- .../nifi-framework-nar-bom/pom.xml | 6 + .../nifi-framework-nar/pom.xml | 5 + .../apache/nifi/remote/RemoteNiFiUtils.java | 6 +- .../nifi-web/nifi-web-api/pom.xml | 5 + .../nifi/web/api/ApplicationResource.java | 36 +- .../nifi/web/api/AuthenticationResource.java | 2 +- .../nifi/web/api/TestApplicationResource.java | 37 +- .../web/api/TestDataTransferResource.java | 10 +- .../nifi-web/nifi-web-security/pom.xml | 5 + .../StandardAuthenticationEntryPoint.java | 2 +- .../StandardCookieCsrfTokenRepository.java | 2 +- .../web/OidcBearerTokenRefreshFilter.java | 2 +- ...tandardAuthorizationRequestRepository.java | 2 +- ...ardOAuth2AuthorizationRequestResolver.java | 2 +- .../oidc/logout/OidcLogoutSuccessHandler.java | 2 +- .../OidcAuthenticationSuccessHandler.java | 2 +- ...ndardRelyingPartyRegistrationResolver.java | 2 +- ...dSaml2AuthenticationRequestRepository.java | 2 +- .../Saml2AuthenticationSuccessHandler.java | 2 +- .../logout/Saml2LogoutSuccessHandler.java | 2 +- .../StandardSaml2LogoutRequestRepository.java | 2 +- .../x509/ocsp/OcspCertificateValidator.java | 4 +- .../StandardAuthenticationEntryPointTest.java | 4 +- ...StandardCookieCsrfTokenRepositoryTest.java | 11 +- ...Auth2AuthorizationRequestResolverTest.java | 13 +- .../OidcAuthenticationSuccessHandlerTest.java | 4 +- ...dRelyingPartyRegistrationResolverTest.java | 4 +- ...Saml2AuthenticationSuccessHandlerTest.java | 4 +- 43 files changed, 895 insertions(+), 782 deletions(-) create mode 100644 nifi-commons/nifi-web-servlet-shared/pom.xml create mode 100644 nifi-commons/nifi-web-servlet-shared/src/main/java/org/apache/nifi/web/servlet/shared/ProxyHeader.java rename nifi-commons/{nifi-web-utils/src/main/java/org/apache/nifi/web/util => nifi-web-servlet-shared/src/main/java/org/apache/nifi/web/servlet/shared}/RequestUriBuilder.java (78%) create mode 100644 nifi-commons/nifi-web-servlet-shared/src/main/java/org/apache/nifi/web/servlet/shared/RequestUriProvider.java create mode 100644 nifi-commons/nifi-web-servlet-shared/src/main/java/org/apache/nifi/web/servlet/shared/StandardRequestUriProvider.java rename nifi-commons/{nifi-web-utils/src/test/java/org/apache/nifi/web/util => nifi-web-servlet-shared/src/test/java/org/apache/nifi/web/servlet/shared}/RequestUriBuilderTest.java (80%) create mode 100644 nifi-commons/nifi-web-servlet-shared/src/test/java/org/apache/nifi/web/servlet/shared/StandardRequestUriProviderTest.java delete mode 100644 nifi-commons/nifi-web-utils/src/main/java/org/apache/nifi/web/filter/SanitizeContextPathFilter.java create mode 100644 nifi-commons/nifi-web-utils/src/main/java/org/apache/nifi/web/util/WebClientUtils.java delete mode 100644 nifi-commons/nifi-web-utils/src/main/java/org/apache/nifi/web/util/WebUtils.java delete mode 100644 nifi-commons/nifi-web-utils/src/test/java/org/apache/nifi/web/filter/SanitizeContextPathFilterTest.java delete mode 100644 nifi-commons/nifi-web-utils/src/test/java/org/apache/nifi/web/util/WebUtilsTest.java diff --git a/nifi-commons/nifi-web-servlet-shared/pom.xml b/nifi-commons/nifi-web-servlet-shared/pom.xml new file mode 100644 index 000000000000..8278c2288914 --- /dev/null +++ b/nifi-commons/nifi-web-servlet-shared/pom.xml @@ -0,0 +1,32 @@ + + + + 4.0.0 + + org.apache.nifi + nifi-commons + 2.0.0-SNAPSHOT + + nifi-web-servlet-shared + Shared classes for handling HTTP Servlet requests and responses + + + jakarta.servlet + jakarta.servlet-api + ${servlet-api.version} + + + diff --git a/nifi-commons/nifi-web-servlet-shared/src/main/java/org/apache/nifi/web/servlet/shared/ProxyHeader.java b/nifi-commons/nifi-web-servlet-shared/src/main/java/org/apache/nifi/web/servlet/shared/ProxyHeader.java new file mode 100644 index 000000000000..ffba485d12f4 --- /dev/null +++ b/nifi-commons/nifi-web-servlet-shared/src/main/java/org/apache/nifi/web/servlet/shared/ProxyHeader.java @@ -0,0 +1,52 @@ +/* + * 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.servlet.shared; + +/** + * Enumeration of supported Proxy Headers that provide information about the original request properties + */ +public enum ProxyHeader { + HOST("Host"), + + PROXY_CONTEXT_PATH("X-ProxyContextPath"), + + PROXY_SCHEME("X-ProxyScheme"), + + PROXY_HOST("X-ProxyHost"), + + PROXY_PORT("X-ProxyPort"), + + FORWARDED_CONTEXT("X-Forwarded-Context"), + + FORWARDED_PREFIX("X-Forwarded-Prefix"), + + FORWARDED_PROTO("X-Forwarded-Proto"), + + FORWARDED_HOST("X-Forwarded-Host"), + + FORWARDED_PORT("X-Forwarded-Port"); + + private final String header; + + ProxyHeader(final String header) { + this.header = header; + } + + public String getHeader() { + return header; + } +} diff --git a/nifi-commons/nifi-web-utils/src/main/java/org/apache/nifi/web/util/RequestUriBuilder.java b/nifi-commons/nifi-web-servlet-shared/src/main/java/org/apache/nifi/web/servlet/shared/RequestUriBuilder.java similarity index 78% rename from nifi-commons/nifi-web-utils/src/main/java/org/apache/nifi/web/util/RequestUriBuilder.java rename to nifi-commons/nifi-web-servlet-shared/src/main/java/org/apache/nifi/web/servlet/shared/RequestUriBuilder.java index 8bf204e6056e..2142c2dfe0fe 100644 --- a/nifi-commons/nifi-web-utils/src/main/java/org/apache/nifi/web/util/RequestUriBuilder.java +++ b/nifi-commons/nifi-web-servlet-shared/src/main/java/org/apache/nifi/web/servlet/shared/RequestUriBuilder.java @@ -14,9 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.nifi.web.util; - -import org.apache.commons.lang3.StringUtils; +package org.apache.nifi.web.servlet.shared; import jakarta.servlet.ServletContext; import jakarta.servlet.http.HttpServletRequest; @@ -72,12 +70,9 @@ public static RequestUriBuilder fromHttpServletRequest(final HttpServletRequest * @return Request URI Builder */ public static RequestUriBuilder fromHttpServletRequest(final HttpServletRequest httpServletRequest, final List allowedContextPaths) { - final String scheme = StringUtils.defaultIfEmpty(WebUtils.determineProxiedScheme(httpServletRequest), httpServletRequest.getScheme()); - final String host = WebUtils.determineProxiedHost(httpServletRequest); - final int port = WebUtils.getServerPort(httpServletRequest); - final String contextPath = WebUtils.determineContextPath(httpServletRequest); - WebUtils.verifyContextPath(allowedContextPaths, contextPath); - return new RequestUriBuilder(scheme, host, port, contextPath); + final RequestUriProvider requestUriProvider = new StandardRequestUriProvider(allowedContextPaths); + final URI requestUri = requestUriProvider.getRequestUri(httpServletRequest); + return new RequestUriBuilder(requestUri.getScheme(), requestUri.getHost(), requestUri.getPort(), requestUri.getPath()); } /** @@ -109,7 +104,7 @@ public RequestUriBuilder fragment(final String fragment) { * @throws IllegalArgumentException Thrown on URI syntax exceptions */ public URI build() { - final String resourcePath = StringUtils.join(contextPath, path); + final String resourcePath = getResourcePath(); try { return new URI(scheme, null, host, port, resourcePath, null, fragment); } catch (final URISyntaxException e) { @@ -118,9 +113,29 @@ public URI build() { } private static List getAllowedContextPathsConfigured(final HttpServletRequest httpServletRequest) { + final List allowedContextPathsConfigured; + final ServletContext servletContext = httpServletRequest.getServletContext(); final String allowedContextPathsParameter = servletContext.getInitParameter(ALLOWED_CONTEXT_PATHS_PARAMETER); - final String[] allowedContextPathsParsed = StringUtils.split(allowedContextPathsParameter, COMMA_SEPARATOR); - return allowedContextPathsParsed == null ? Collections.emptyList() : Arrays.asList(allowedContextPathsParsed); + if (allowedContextPathsParameter == null) { + allowedContextPathsConfigured = Collections.emptyList(); + } else { + final String[] allowedContextPathsParsed = allowedContextPathsParameter.split(COMMA_SEPARATOR); + allowedContextPathsConfigured = Arrays.asList(allowedContextPathsParsed); + } + + return allowedContextPathsConfigured; + } + + private String getResourcePath() { + final String resourcePath; + + if (path == null) { + resourcePath = contextPath; + } else { + resourcePath = contextPath + path; + } + + return resourcePath; } } diff --git a/nifi-commons/nifi-web-servlet-shared/src/main/java/org/apache/nifi/web/servlet/shared/RequestUriProvider.java b/nifi-commons/nifi-web-servlet-shared/src/main/java/org/apache/nifi/web/servlet/shared/RequestUriProvider.java new file mode 100644 index 000000000000..4c110d6586b7 --- /dev/null +++ b/nifi-commons/nifi-web-servlet-shared/src/main/java/org/apache/nifi/web/servlet/shared/RequestUriProvider.java @@ -0,0 +1,34 @@ +/* + * 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.servlet.shared; + +import jakarta.servlet.http.HttpServletRequest; + +import java.net.URI; + +/** + * Abstraction for resolving and returning an HTTP Request URI based on presented headers and configured properties + */ +public interface RequestUriProvider { + /** + * Get Request URI from HTTP Servlet Request containing optional headers + * + * @param request HTTP Servlet Request + * @return Request URI + */ + URI getRequestUri(HttpServletRequest request); +} diff --git a/nifi-commons/nifi-web-servlet-shared/src/main/java/org/apache/nifi/web/servlet/shared/StandardRequestUriProvider.java b/nifi-commons/nifi-web-servlet-shared/src/main/java/org/apache/nifi/web/servlet/shared/StandardRequestUriProvider.java new file mode 100644 index 000000000000..fabc898d408e --- /dev/null +++ b/nifi-commons/nifi-web-servlet-shared/src/main/java/org/apache/nifi/web/servlet/shared/StandardRequestUriProvider.java @@ -0,0 +1,195 @@ +/* + * 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.servlet.shared; + +import jakarta.servlet.http.HttpServletRequest; + +import java.net.URI; +import java.net.URISyntaxException; +import java.util.Arrays; +import java.util.List; +import java.util.Objects; +import java.util.function.Predicate; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Standard implementation of Request URI Provider with allowed hosts and context paths + */ +public class StandardRequestUriProvider implements RequestUriProvider { + private static final Pattern HOST_PATTERN = Pattern.compile("^([^:]+):?([1-9][0-9]{2,4})?$"); + + private static final Pattern HOST_PORT_REQUIRED_PATTERN = Pattern.compile("^[^:]+:([1-9][0-9]{2,4})$"); + + private static final Pattern SCHEME_PATTERN = Pattern.compile("^https?$"); + + private static final int FIRST_GROUP = 1; + + private static final int MINIMUM_PORT_NUMBER = 100; + + private static final int MAXIMUM_PORT_NUMBER = 65535; + + private static final String EMPTY_PATH = ""; + + private static final String ROOT_PATH = "/"; + + private final List allowedContextPaths; + + public StandardRequestUriProvider(final List allowedContextPaths) { + this.allowedContextPaths = Objects.requireNonNull(allowedContextPaths); + } + + /** + * Get Request URI from HTTP Servlet Request containing optional headers and validated against allowed context paths + * + * @param request HTTP Servlet Request + * @return Request URI + */ + @Override + public URI getRequestUri(final HttpServletRequest request) { + Objects.requireNonNull(request, "HTTP Servlet Request required"); + + final String scheme = getScheme(request); + final String host = getHost(request); + final int port = getPort(request); + final String path = getPath(request); + + try { + return new URI(scheme, null, host, port, path, null, null); + } catch (final URISyntaxException e) { + throw new IllegalArgumentException("Request URI construction failed", e); + } + } + + private String getScheme(final HttpServletRequest request) { + final String scheme; + + final String requestScheme = request.getScheme(); + final String headerScheme = getFirstHeader(request, ProxyHeader.PROXY_SCHEME, ProxyHeader.FORWARDED_PROTO); + if (headerScheme == null) { + scheme = requestScheme; + } else { + final Matcher matcher = SCHEME_PATTERN.matcher(headerScheme); + if (matcher.matches()) { + scheme = headerScheme; + } else { + scheme = requestScheme; + } + } + + return scheme; + } + + private String getHost(final HttpServletRequest request) { + final String host; + + final String serverName = request.getServerName(); + final String headerHost = getFirstHeader(request, ProxyHeader.PROXY_HOST, ProxyHeader.FORWARDED_HOST, ProxyHeader.HOST); + if (headerHost == null) { + host = serverName; + } else { + final Matcher matcher = HOST_PATTERN.matcher(headerHost); + if (matcher.matches()) { + host = matcher.group(FIRST_GROUP); + } else { + host = serverName; + } + } + + return host; + } + + private int getPort(final HttpServletRequest request) { + final int port; + + final int serverPort = request.getServerPort(); + final String headerHost = getFirstHeader(request, ProxyHeader.PROXY_HOST, ProxyHeader.FORWARDED_HOST); + if (headerHost == null) { + port = getProxyPort(request); + } else { + final Matcher matcher = HOST_PORT_REQUIRED_PATTERN.matcher(headerHost); + if (matcher.matches()) { + final String headerPort = matcher.group(FIRST_GROUP); + port = getParsedPort(headerPort, serverPort); + } else { + port = getProxyPort(request); + } + } + + return port; + } + + private int getProxyPort(final HttpServletRequest request) { + final int port; + + final int serverPort = request.getServerPort(); + final String headerPort = getFirstHeader(request, ProxyHeader.PROXY_PORT, ProxyHeader.FORWARDED_PORT); + if (headerPort == null) { + port = serverPort; + } else { + port = getParsedPort(headerPort, serverPort); + } + + return port; + } + + private int getParsedPort(final String headerPort, final int serverPort) { + int port; + + try { + final int parsedPort = Integer.parseInt(headerPort); + if (parsedPort < MINIMUM_PORT_NUMBER || parsedPort > MAXIMUM_PORT_NUMBER) { + port = serverPort; + } else { + port = parsedPort; + } + } catch (final Exception e) { + port = serverPort; + } + + return port; + } + + private String getPath(final HttpServletRequest request) { + final String path; + + final String headerPath = getFirstHeader(request, ProxyHeader.PROXY_CONTEXT_PATH, ProxyHeader.FORWARDED_CONTEXT, ProxyHeader.FORWARDED_PREFIX); + if (headerPath == null) { + path = EMPTY_PATH; + } else if (ROOT_PATH.equals(headerPath)) { + path = ROOT_PATH; + } else { + if (allowedContextPaths.contains(headerPath)) { + path = headerPath; + } else { + throw new IllegalArgumentException("Request Header Context Path not allowed based on properties [nifi.web.proxy.context.path]"); + } + } + + return path; + } + + private String getFirstHeader(final HttpServletRequest request, final ProxyHeader... proxyHeaders) { + return Arrays.stream(proxyHeaders) + .map(ProxyHeader::getHeader) + .map(request::getHeader) + .filter(Objects::nonNull) + .filter(Predicate.not(String::isBlank)) + .findFirst() + .orElse(null); + } +} diff --git a/nifi-commons/nifi-web-utils/src/test/java/org/apache/nifi/web/util/RequestUriBuilderTest.java b/nifi-commons/nifi-web-servlet-shared/src/test/java/org/apache/nifi/web/servlet/shared/RequestUriBuilderTest.java similarity index 80% rename from nifi-commons/nifi-web-utils/src/test/java/org/apache/nifi/web/util/RequestUriBuilderTest.java rename to nifi-commons/nifi-web-servlet-shared/src/test/java/org/apache/nifi/web/servlet/shared/RequestUriBuilderTest.java index 3b3a8fdcf922..c3d03a5dd491 100644 --- a/nifi-commons/nifi-web-utils/src/test/java/org/apache/nifi/web/util/RequestUriBuilderTest.java +++ b/nifi-commons/nifi-web-servlet-shared/src/test/java/org/apache/nifi/web/servlet/shared/RequestUriBuilderTest.java @@ -14,9 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.nifi.web.util; +package org.apache.nifi.web.servlet.shared; -import org.apache.commons.lang3.StringUtils; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; @@ -24,8 +23,8 @@ import jakarta.servlet.http.HttpServletRequest; import java.net.URI; -import java.util.Arrays; import java.util.Collections; +import java.util.List; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; @@ -41,10 +40,14 @@ public class RequestUriBuilderTest { private static final String HOST = "localhost.local"; + private static final String FRAGMENT = "section"; + private static final int PORT = 443; private static final String CONTEXT_PATH = "/context-path"; + private static final String EMPTY = ""; + @Mock private HttpServletRequest httpServletRequest; @@ -61,7 +64,7 @@ public void testFromHttpServletRequestBuild() { assertEquals(SCHEME, uri.getScheme()); assertEquals(HOST, uri.getHost()); assertEquals(PORT, uri.getPort()); - assertEquals(StringUtils.EMPTY, uri.getPath()); + assertEquals(EMPTY, uri.getPath()); } @Test @@ -71,7 +74,7 @@ public void testFromHttpServletRequestPathBuild() { lenient().when(httpServletRequest.getHeader(eq(HOST_HEADER))).thenReturn(HOST); final RequestUriBuilder builder = RequestUriBuilder.fromHttpServletRequest(httpServletRequest, Collections.emptyList()); - builder.path(CONTEXT_PATH); + builder.fragment(FRAGMENT).path(CONTEXT_PATH); final URI uri = builder.build(); assertNotNull(uri); @@ -79,16 +82,17 @@ public void testFromHttpServletRequestPathBuild() { assertEquals(HOST, uri.getHost()); assertEquals(PORT, uri.getPort()); assertEquals(CONTEXT_PATH, uri.getPath()); + assertEquals(FRAGMENT, uri.getFragment()); } @Test public void testFromHttpServletRequestProxyHeadersBuild() { - when(httpServletRequest.getHeader(eq(WebUtils.PROXY_SCHEME_HTTP_HEADER))).thenReturn(SCHEME); - when(httpServletRequest.getHeader(eq(WebUtils.PROXY_HOST_HTTP_HEADER))).thenReturn(HOST); - when(httpServletRequest.getHeader(eq(WebUtils.PROXY_PORT_HTTP_HEADER))).thenReturn(Integer.toString(PORT)); - when(httpServletRequest.getHeader(eq(WebUtils.PROXY_CONTEXT_PATH_HTTP_HEADER))).thenReturn(CONTEXT_PATH); + when(httpServletRequest.getHeader(eq(ProxyHeader.PROXY_SCHEME.getHeader()))).thenReturn(SCHEME); + when(httpServletRequest.getHeader(eq(ProxyHeader.PROXY_HOST.getHeader()))).thenReturn(HOST); + when(httpServletRequest.getHeader(eq(ProxyHeader.PROXY_PORT.getHeader()))).thenReturn(Integer.toString(PORT)); + when(httpServletRequest.getHeader(eq(ProxyHeader.PROXY_CONTEXT_PATH.getHeader()))).thenReturn(CONTEXT_PATH); - final RequestUriBuilder builder = RequestUriBuilder.fromHttpServletRequest(httpServletRequest, Arrays.asList(CONTEXT_PATH)); + final RequestUriBuilder builder = RequestUriBuilder.fromHttpServletRequest(httpServletRequest, List.of(CONTEXT_PATH)); final URI uri = builder.build(); assertNotNull(uri); diff --git a/nifi-commons/nifi-web-servlet-shared/src/test/java/org/apache/nifi/web/servlet/shared/StandardRequestUriProviderTest.java b/nifi-commons/nifi-web-servlet-shared/src/test/java/org/apache/nifi/web/servlet/shared/StandardRequestUriProviderTest.java new file mode 100644 index 000000000000..f717e3ccc0f4 --- /dev/null +++ b/nifi-commons/nifi-web-servlet-shared/src/test/java/org/apache/nifi/web/servlet/shared/StandardRequestUriProviderTest.java @@ -0,0 +1,349 @@ +/* + * 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.servlet.shared; + +import jakarta.servlet.http.HttpServletRequest; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.net.URI; +import java.util.Collections; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.when; + +@ExtendWith(MockitoExtension.class) +class StandardRequestUriProviderTest { + private static final String SCHEME = "http"; + + private static final String HTTPS_SCHEME = "https"; + + private static final String SERVER = "localhost"; + + private static final String HOST = "localhost.local"; + + private static final int PORT = 443; + + private static final int APPLICATION_PORT = 8443; + + private static final String HOST_WITH_PORT_FORMAT = "%s:%d"; + + private static final String HOST_WITH_PORT = HOST_WITH_PORT_FORMAT.formatted(HOST, PORT); + + private static final String HOST_INVALID = "0000:0000:0000:0000:0000:0000:0000:0000"; + + private static final String CONTEXT_PATH = "/context-path"; + + private static final String ROOT_PATH = "/"; + + private static final String EMPTY = ""; + + @Mock + private HttpServletRequest request; + + @BeforeEach + void setRequest() { + when(request.getScheme()).thenReturn(SCHEME); + when(request.getServerName()).thenReturn(SERVER); + when(request.getServerPort()).thenReturn(PORT); + } + + @Test + void testGetRequestUri() { + final StandardRequestUriProvider provider = new StandardRequestUriProvider(Collections.emptyList()); + + final URI requestUri = provider.getRequestUri(request); + + assertSchemeMatched(requestUri, SCHEME); + } + + @Test + void testGetRequestUriProxyScheme() { + final StandardRequestUriProvider provider = new StandardRequestUriProvider(Collections.emptyList()); + + when(request.getHeader(eq(ProxyHeader.PROXY_SCHEME.getHeader()))).thenReturn(HTTPS_SCHEME); + final URI requestUri = provider.getRequestUri(request); + + assertSchemeMatched(requestUri, HTTPS_SCHEME); + } + + @Test + void testGetRequestUriForwardedProto() { + final StandardRequestUriProvider provider = new StandardRequestUriProvider(Collections.emptyList()); + + when(request.getHeader(eq(ProxyHeader.PROXY_SCHEME.getHeader()))).thenReturn(null); + when(request.getHeader(eq(ProxyHeader.FORWARDED_PROTO.getHeader()))).thenReturn(HTTPS_SCHEME); + final URI requestUri = provider.getRequestUri(request); + + assertSchemeMatched(requestUri, HTTPS_SCHEME); + } + + @Test + void testGetRequestUriProxySchemeInvalid() { + final StandardRequestUriProvider provider = new StandardRequestUriProvider(Collections.emptyList()); + + when(request.getHeader(eq(ProxyHeader.PROXY_SCHEME.getHeader()))).thenReturn(String.class.getSimpleName()); + final URI requestUri = provider.getRequestUri(request); + + assertSchemeMatched(requestUri, SCHEME); + } + + @Test + void testGetRequestUriProxyHost() { + final StandardRequestUriProvider provider = new StandardRequestUriProvider(Collections.emptyList()); + + when(request.getHeader(anyString())).thenReturn(null); + when(request.getHeader(eq(ProxyHeader.PROXY_HOST.getHeader()))).thenReturn(HOST); + final URI requestUri = provider.getRequestUri(request); + + assertHostMatched(requestUri, HOST); + } + + @Test + void testGetRequestUriForwardedHost() { + final StandardRequestUriProvider provider = new StandardRequestUriProvider(Collections.emptyList()); + + when(request.getHeader(anyString())).thenReturn(null); + when(request.getHeader(eq(ProxyHeader.FORWARDED_HOST.getHeader()))).thenReturn(HOST); + final URI requestUri = provider.getRequestUri(request); + + assertHostMatched(requestUri, HOST); + } + + @Test + void testGetRequestUriHost() { + final StandardRequestUriProvider provider = new StandardRequestUriProvider(Collections.emptyList()); + + when(request.getHeader(anyString())).thenReturn(null); + when(request.getHeader(eq(ProxyHeader.HOST.getHeader()))).thenReturn(HOST); + final URI requestUri = provider.getRequestUri(request); + + assertHostMatched(requestUri, HOST); + } + + @Test + void testGetRequestUriHostWithPort() { + final StandardRequestUriProvider provider = new StandardRequestUriProvider(Collections.emptyList()); + + when(request.getHeader(anyString())).thenReturn(null); + when(request.getHeader(eq(ProxyHeader.HOST.getHeader()))).thenReturn(HOST_WITH_PORT); + final URI requestUri = provider.getRequestUri(request); + + assertHostMatched(requestUri, HOST); + } + + @Test + void testGetRequestUriHostInvalid() { + final StandardRequestUriProvider provider = new StandardRequestUriProvider(Collections.emptyList()); + + when(request.getHeader(anyString())).thenReturn(null); + when(request.getHeader(eq(ProxyHeader.HOST.getHeader()))).thenReturn(HOST_INVALID); + final URI requestUri = provider.getRequestUri(request); + + assertHostMatched(requestUri, SERVER); + } + + @Test + void testGetRequestUriProxyHostPort() { + final StandardRequestUriProvider provider = new StandardRequestUriProvider(Collections.emptyList()); + + when(request.getHeader(anyString())).thenReturn(null); + + final String proxyHost = HOST_WITH_PORT_FORMAT.formatted(HOST, APPLICATION_PORT); + + when(request.getHeader(eq(ProxyHeader.PROXY_HOST.getHeader()))).thenReturn(proxyHost); + final URI requestUri = provider.getRequestUri(request); + + assertHostPortMatched(requestUri, HOST, APPLICATION_PORT); + } + + @Test + void testGetRequestUriForwardedHostPort() { + final StandardRequestUriProvider provider = new StandardRequestUriProvider(Collections.emptyList()); + + when(request.getHeader(anyString())).thenReturn(null); + + final String proxyHost = HOST_WITH_PORT_FORMAT.formatted(HOST, APPLICATION_PORT); + + when(request.getHeader(eq(ProxyHeader.FORWARDED_HOST.getHeader()))).thenReturn(proxyHost); + final URI requestUri = provider.getRequestUri(request); + + assertHostPortMatched(requestUri, HOST, APPLICATION_PORT); + } + + @Test + void testGetRequestUriForwardedHostPortInvalid() { + final StandardRequestUriProvider provider = new StandardRequestUriProvider(Collections.emptyList()); + + when(request.getHeader(anyString())).thenReturn(null); + + final String proxyHost = HOST_WITH_PORT_FORMAT.formatted(HOST, Integer.MAX_VALUE); + + when(request.getHeader(eq(ProxyHeader.FORWARDED_HOST.getHeader()))).thenReturn(proxyHost); + final URI requestUri = provider.getRequestUri(request); + + assertHostPortMatched(requestUri, SERVER, PORT); + } + + @Test + void testGetRequestUriProxyPort() { + final StandardRequestUriProvider provider = new StandardRequestUriProvider(Collections.emptyList()); + + when(request.getHeader(anyString())).thenReturn(null); + when(request.getHeader(eq(ProxyHeader.PROXY_PORT.getHeader()))).thenReturn(Integer.toString(APPLICATION_PORT)); + final URI requestUri = provider.getRequestUri(request); + + assertHostPortMatched(requestUri, SERVER, APPLICATION_PORT); + } + + @Test + void testGetRequestUriForwardedPort() { + final StandardRequestUriProvider provider = new StandardRequestUriProvider(Collections.emptyList()); + + when(request.getHeader(anyString())).thenReturn(null); + when(request.getHeader(eq(ProxyHeader.FORWARDED_PORT.getHeader()))).thenReturn(Integer.toString(APPLICATION_PORT)); + final URI requestUri = provider.getRequestUri(request); + + assertHostPortMatched(requestUri, SERVER, APPLICATION_PORT); + } + + @Test + void testGetRequestUriProxyPortInvalid() { + final StandardRequestUriProvider provider = new StandardRequestUriProvider(Collections.emptyList()); + + when(request.getHeader(anyString())).thenReturn(null); + when(request.getHeader(eq(ProxyHeader.PROXY_PORT.getHeader()))).thenReturn(Integer.toString(Integer.MAX_VALUE)); + final URI requestUri = provider.getRequestUri(request); + + assertHostPortMatched(requestUri, SERVER, PORT); + } + + @Test + void testGetRequestUriProxyPortInvalidString() { + final StandardRequestUriProvider provider = new StandardRequestUriProvider(Collections.emptyList()); + + when(request.getHeader(anyString())).thenReturn(null); + when(request.getHeader(eq(ProxyHeader.PROXY_PORT.getHeader()))).thenReturn(String.class.getSimpleName()); + final URI requestUri = provider.getRequestUri(request); + + assertHostPortMatched(requestUri, SERVER, PORT); + } + + @Test + void testGetRequestUriRootPath() { + final StandardRequestUriProvider provider = new StandardRequestUriProvider(Collections.emptyList()); + + when(request.getHeader(anyString())).thenReturn(null); + when(request.getHeader(eq(ProxyHeader.PROXY_CONTEXT_PATH.getHeader()))).thenReturn(ROOT_PATH); + final URI requestUri = provider.getRequestUri(request); + + assertPathMatched(requestUri, ROOT_PATH); + } + + @Test + void testGetRequestUriContextPathNotAllowed() { + final StandardRequestUriProvider provider = new StandardRequestUriProvider(Collections.emptyList()); + + when(request.getHeader(anyString())).thenReturn(null); + when(request.getHeader(eq(ProxyHeader.PROXY_CONTEXT_PATH.getHeader()))).thenReturn(CONTEXT_PATH); + assertThrows(IllegalArgumentException.class, () -> provider.getRequestUri(request)); + } + + @Test + void testGetRequestUriProxyContextPath() { + final StandardRequestUriProvider provider = new StandardRequestUriProvider(List.of(CONTEXT_PATH)); + + when(request.getHeader(anyString())).thenReturn(null); + when(request.getHeader(eq(ProxyHeader.PROXY_CONTEXT_PATH.getHeader()))).thenReturn(CONTEXT_PATH); + final URI requestUri = provider.getRequestUri(request); + + assertPathMatched(requestUri, CONTEXT_PATH); + } + + @Test + void testGetRequestUriProxyContextPathBlank() { + final StandardRequestUriProvider provider = new StandardRequestUriProvider(List.of(CONTEXT_PATH)); + + when(request.getHeader(anyString())).thenReturn(null); + when(request.getHeader(eq(ProxyHeader.PROXY_CONTEXT_PATH.getHeader()))).thenReturn(EMPTY); + final URI requestUri = provider.getRequestUri(request); + + assertPathMatched(requestUri, EMPTY); + } + + @Test + void testGetRequestUriForwardedContext() { + final StandardRequestUriProvider provider = new StandardRequestUriProvider(List.of(CONTEXT_PATH)); + + when(request.getHeader(anyString())).thenReturn(null); + when(request.getHeader(eq(ProxyHeader.FORWARDED_CONTEXT.getHeader()))).thenReturn(CONTEXT_PATH); + final URI requestUri = provider.getRequestUri(request); + + assertPathMatched(requestUri, CONTEXT_PATH); + } + + @Test + void testGetRequestUriForwardedPrefix() { + final StandardRequestUriProvider provider = new StandardRequestUriProvider(List.of(CONTEXT_PATH)); + + when(request.getHeader(anyString())).thenReturn(null); + when(request.getHeader(eq(ProxyHeader.FORWARDED_PREFIX.getHeader()))).thenReturn(CONTEXT_PATH); + final URI requestUri = provider.getRequestUri(request); + + assertPathMatched(requestUri, CONTEXT_PATH); + } + + private void assertSchemeMatched(final URI requestUri, final String scheme) { + assertNotNull(requestUri); + assertEquals(scheme, requestUri.getScheme()); + assertEquals(SERVER, requestUri.getHost()); + assertEquals(PORT, requestUri.getPort()); + assertEquals(EMPTY, requestUri.getPath()); + } + + private void assertHostMatched(final URI requestUri, final String host) { + assertNotNull(requestUri); + assertEquals(SCHEME, requestUri.getScheme()); + assertEquals(host, requestUri.getHost()); + assertEquals(PORT, requestUri.getPort()); + assertEquals(EMPTY, requestUri.getPath()); + } + + private void assertHostPortMatched(final URI requestUri, final String host, final int port) { + assertNotNull(requestUri); + assertEquals(SCHEME, requestUri.getScheme()); + assertEquals(host, requestUri.getHost()); + assertEquals(port, requestUri.getPort()); + assertEquals(EMPTY, requestUri.getPath()); + } + + private void assertPathMatched(final URI requestUri, final String path) { + assertNotNull(requestUri); + assertEquals(SCHEME, requestUri.getScheme()); + assertEquals(SERVER, requestUri.getHost()); + assertEquals(PORT, requestUri.getPort()); + assertEquals(path, requestUri.getPath()); + } +} diff --git a/nifi-commons/nifi-web-utils/pom.xml b/nifi-commons/nifi-web-utils/pom.xml index e92e89df379f..5e518da025ad 100644 --- a/nifi-commons/nifi-web-utils/pom.xml +++ b/nifi-commons/nifi-web-utils/pom.xml @@ -22,14 +22,6 @@ nifi-web-utils - - org.slf4j - slf4j-api - - - org.apache.commons - commons-lang3 - org.glassfish.jersey.core jersey-client @@ -54,11 +46,6 @@ jakarta.ws.rs jakarta.ws.rs-api - - jakarta.servlet - jakarta.servlet-api - ${servlet-api.version} - org.apache.httpcomponents httpclient 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 deleted file mode 100644 index 7e6405d82c9f..000000000000 --- a/nifi-commons/nifi-web-utils/src/main/java/org/apache/nifi/web/filter/SanitizeContextPathFilter.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * 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 java.io.IOException; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import jakarta.servlet.Filter; -import jakarta.servlet.FilterChain; -import jakarta.servlet.FilterConfig; -import jakarta.servlet.ServletException; -import jakarta.servlet.ServletRequest; -import jakarta.servlet.ServletResponse; - -import org.apache.commons.lang3.StringUtils; -import org.apache.nifi.web.util.WebUtils; - -/** - * This filter intercepts a request and populates the {@code contextPath} attribute on the request with a sanitized value (originally) retrieved from {@code nifi.properties}. - */ -public class SanitizeContextPathFilter implements Filter { - private static final String ALLOWED_CONTEXT_PATHS_PARAMETER_NAME = "allowedContextPaths"; - - private String allowedContextPaths = ""; - private List parsedAllowedContextPaths = Collections.emptyList(); - - @Override - public void init(FilterConfig filterConfig) throws ServletException { - String providedAllowedList = filterConfig.getServletContext().getInitParameter(ALLOWED_CONTEXT_PATHS_PARAMETER_NAME); - - if (StringUtils.isNotBlank(providedAllowedList)) { - allowedContextPaths = providedAllowedList; - parsedAllowedContextPaths = Arrays.asList(StringUtils.split(providedAllowedList, ',')); - } - } - - @Override - public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException { - // Inject the contextPath attribute into the request - injectContextPathAttribute(request); - - // Pass execution to the next filter in the chain - filterChain.doFilter(request, response); - } - - /** - * 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, parsedAllowedContextPaths, ""); - request.setAttribute("contextPath", contextPath); - } - - @Override - public void destroy() { - } - - /** - * Getter for allowed context paths. Cannot be package-private because of an issue where the package is scoped per classloader. - * - * @return the allowed context path(s) - */ - protected String getAllowedContextPaths() { - return allowedContextPaths; - } -} diff --git a/nifi-commons/nifi-web-utils/src/main/java/org/apache/nifi/web/util/WebClientUtils.java b/nifi-commons/nifi-web-utils/src/main/java/org/apache/nifi/web/util/WebClientUtils.java new file mode 100644 index 000000000000..9dc24d1ecbcd --- /dev/null +++ b/nifi-commons/nifi-web-utils/src/main/java/org/apache/nifi/web/util/WebClientUtils.java @@ -0,0 +1,89 @@ +/* + * 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.util; + +import org.apache.http.conn.ssl.DefaultHostnameVerifier; +import org.glassfish.jersey.client.ClientConfig; +import org.glassfish.jersey.jackson.internal.jackson.jaxrs.json.JacksonJaxbJsonProvider; + +import javax.net.ssl.SSLContext; +import jakarta.ws.rs.client.Client; +import jakarta.ws.rs.client.ClientBuilder; + +/** + * Client utilities for Jakarta RESTful Web Services + */ +public final class WebClientUtils { + + private WebClientUtils() { + } + + /** + * Creates a client for non-secure requests. The client will be created + * using the given configuration. Additionally, the client will be + * automatically configured for JSON serialization/deserialization. + * + * @param config client configuration + * @return a Client instance + */ + public static Client createClient(final ClientConfig config) { + return createClientHelper(config, null); + } + + /** + * Creates a client for secure requests. The client will be created using + * the given configuration and security context. Additionally, the client + * will be automatically configured for JSON serialization/deserialization. + * + * @param config client configuration + * @param ctx security context + * @return a Client instance + */ + public static Client createClient(final ClientConfig config, final SSLContext ctx) { + return createClientHelper(config, ctx); + } + + /** + * A helper method for creating clients. The client will be created using + * the given configuration and security context. Additionally, the client + * will be automatically configured for JSON serialization/deserialization. + * + * @param config client configuration + * @param ctx security context, which may be null for non-secure client + * creation + * @return a Client instance + */ + private static Client createClientHelper(final ClientConfig config, final SSLContext ctx) { + + ClientBuilder clientBuilder = ClientBuilder.newBuilder(); + + if (config != null) { + clientBuilder = clientBuilder.withConfig(config); + } + + if (ctx != null) { + + // Apache http DefaultHostnameVerifier that checks subject alternative names against the hostname of the URI + clientBuilder = clientBuilder.sslContext(ctx).hostnameVerifier(new DefaultHostnameVerifier()); + } + + clientBuilder = clientBuilder.register(ObjectMapperResolver.class).register(JacksonJaxbJsonProvider.class); + + return clientBuilder.build(); + + } +} 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 deleted file mode 100644 index b838cf4d44c6..000000000000 --- a/nifi-commons/nifi-web-utils/src/main/java/org/apache/nifi/web/util/WebUtils.java +++ /dev/null @@ -1,349 +0,0 @@ -/* - * 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.util; - -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 javax.net.ssl.SSLContext; -import jakarta.servlet.ServletRequest; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.ws.rs.client.Client; -import jakarta.ws.rs.client.ClientBuilder; -import jakarta.ws.rs.core.UriBuilderException; -import java.util.List; -import java.util.stream.Stream; - -/** - * Common utilities related to web development. - */ -public final class WebUtils { - - private static final Logger logger = LoggerFactory.getLogger(WebUtils.class); - - public static final String PROXY_SCHEME_HTTP_HEADER = "X-ProxyScheme"; - public static final String PROXY_HOST_HTTP_HEADER = "X-ProxyHost"; - public static final String PROXY_PORT_HTTP_HEADER = "X-ProxyPort"; - - public static final String FORWARDED_PROTO_HTTP_HEADER = "X-Forwarded-Proto"; - public static final String FORWARDED_HOST_HTTP_HEADER = "X-Forwarded-Host"; - public static final String FORWARDED_PORT_HTTP_HEADER = "X-Forwarded-Port"; - - public static final String PROXY_CONTEXT_PATH_HTTP_HEADER = "X-ProxyContextPath"; - public static final String FORWARDED_CONTEXT_HTTP_HEADER = "X-Forwarded-Context"; - public static final String FORWARDED_PREFIX_HTTP_HEADER = "X-Forwarded-Prefix"; - - private static final String HOST_HEADER = "Host"; - - private static final String EMPTY = ""; - - private WebUtils() { - } - - /** - * Creates a client for non-secure requests. The client will be created - * using the given configuration. Additionally, the client will be - * automatically configured for JSON serialization/deserialization. - * - * @param config client configuration - * @return a Client instance - */ - public static Client createClient(final ClientConfig config) { - return createClientHelper(config, null); - } - - /** - * Creates a client for secure requests. The client will be created using - * the given configuration and security context. Additionally, the client - * will be automatically configured for JSON serialization/deserialization. - * - * @param config client configuration - * @param ctx security context - * @return a Client instance - */ - public static Client createClient(final ClientConfig config, final SSLContext ctx) { - return createClientHelper(config, ctx); - } - - /** - * A helper method for creating clients. The client will be created using - * the given configuration and security context. Additionally, the client - * will be automatically configured for JSON serialization/deserialization. - * - * @param config client configuration - * @param ctx security context, which may be null for non-secure client - * creation - * @return a Client instance - */ - private static Client createClientHelper(final ClientConfig config, final SSLContext ctx) { - - ClientBuilder clientBuilder = ClientBuilder.newBuilder(); - - if (config != null) { - clientBuilder = clientBuilder.withConfig(config); - } - - if (ctx != null) { - - // Apache http DefaultHostnameVerifier that checks subject alternative names against the hostname of the URI - clientBuilder = clientBuilder.sslContext(ctx).hostnameVerifier(new DefaultHostnameVerifier()); - } - - clientBuilder = clientBuilder.register(ObjectMapperResolver.class).register(JacksonJaxbJsonProvider.class); - - return clientBuilder.build(); - - } - - /** - * Throws an exception if the provided context path is not in the allowed context paths list. - * - * @param allowedContextPaths 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(final List allowedContextPaths, final String determinedContextPath) throws UriBuilderException { - // If blank, ignore - if (StringUtils.isBlank(determinedContextPath)) { - return; - } - - // Check it against the allowed list - if (!allowedContextPaths.contains(determinedContextPath)) { - final String msg = "The provided context path [" + determinedContextPath + "] was not registered as allowed " + allowedContextPaths; - throw new UriBuilderException(msg); - } - } - - /** - * Returns a normalized context path (leading /, no trailing /). If the parameter is blank, an empty string will be returned. - * - * @param determinedContextPath the raw context path - * @return the normalized context path - */ - public static String normalizeContextPath(String determinedContextPath) { - if (StringUtils.isNotBlank(determinedContextPath)) { - // normalize context path - if (!determinedContextPath.startsWith("/")) { - determinedContextPath = "/" + determinedContextPath; - } - - if (determinedContextPath.endsWith("/")) { - determinedContextPath = determinedContextPath.substring(0, determinedContextPath.length() - 1); - } - - return determinedContextPath; - } else { - return ""; - } - } - - /** - * Returns a "safe" context path value from the request headers to use in a proxy environment. - * This is used on the JSP to build the resource paths for the external resources (CSS, JS, etc.). - * If no headers are present specifying this value, it is an empty string. - * - * @param request the HTTP request - * @param allowedContextPaths 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(final ServletRequest request, final List allowedContextPaths, String jspDisplayName) { - if (StringUtils.isBlank(jspDisplayName)) { - jspDisplayName = "JSP page"; - } - String contextPath = normalizeContextPath(determineContextPath((HttpServletRequest) request)); - try { - verifyContextPath(allowedContextPaths, contextPath); - return contextPath; - } catch (UriBuilderException e) { - logger.error("Error determining context path on {}", jspDisplayName, e); - return EMPTY; - } - } - - /** - * Determines the context path if populated in {@code X-ProxyContextPath}, {@code X-ForwardContext}, - * or {@code X-Forwarded-Prefix} headers. If not populated, returns an empty string. - * - * @param request the HTTP request - * @return the provided context path or an empty string - */ - public static String determineContextPath(final HttpServletRequest request) { - final String proxyContextPath = request.getHeader(PROXY_CONTEXT_PATH_HTTP_HEADER); - final String forwardedContext = request.getHeader(FORWARDED_CONTEXT_HTTP_HEADER); - final String prefix = request.getHeader(FORWARDED_PREFIX_HTTP_HEADER); - - String determinedContextPath = EMPTY; - if (anyNotBlank(proxyContextPath, forwardedContext, prefix)) { - // Implementing preferred order here: PCP, FC, FP - determinedContextPath = Stream.of(proxyContextPath, forwardedContext, prefix) - .filter(StringUtils::isNotBlank).findFirst().orElse(EMPTY); - } - - return determinedContextPath; - } - - /** - * Returns true if any of the provided arguments are not blank. - * - * @param strings a variable number of strings - * @return true if any string has content (not empty or all whitespace) - */ - private static boolean anyNotBlank(String... strings) { - for (String s : strings) { - if (StringUtils.isNotBlank(s)) { - return true; - } - } - return false; - } - - /** - * Returns the value for the first key discovered when inspecting the current request. Will - * return null if there are no keys specified or if none of the specified keys are found. - * - * @param httpServletRequest request - * @param keys http header keys - * @return the value for the first key found, or null if no matching keys found - */ - public static String getFirstHeaderValue(final HttpServletRequest httpServletRequest, final String... keys) { - if (keys == null) { - return null; - } - - for (final String key : keys) { - final String value = httpServletRequest.getHeader(key); - - // if we found an entry for this key, return the value - if (value != null) { - return value; - } - } - - // unable to find any matching keys - return null; - } - - /** - * Determines the scheme based on considering proxy related headers first and then falling back to the scheme of the servlet request. - * - * @param httpServletRequest the request - * @return the determined scheme - */ - public static String determineProxiedScheme(final HttpServletRequest httpServletRequest) { - final String schemeHeaderValue = getFirstHeaderValue(httpServletRequest, PROXY_SCHEME_HTTP_HEADER, FORWARDED_PROTO_HTTP_HEADER); - return StringUtils.isBlank(schemeHeaderValue) ? httpServletRequest.getScheme() : schemeHeaderValue; - } - - /** - * Determines the host based on considering proxy related headers first and falling back to the host of the servlet request. - * - * @param httpServletRequest the request - * @return the determined host - */ - public static String determineProxiedHost(final HttpServletRequest httpServletRequest) { - final String hostHeaderValue = getFirstHeaderValue(httpServletRequest, PROXY_HOST_HTTP_HEADER, FORWARDED_HOST_HTTP_HEADER, HOST_HEADER); - final String proxiedHost = determineProxiedHost(hostHeaderValue); - return StringUtils.isBlank(proxiedHost) ? httpServletRequest.getServerName() : proxiedHost; - } - - /** - * Determines the host from the given header. The header value is intended to come from a header like X-ProxyHost or X-Forwarded-Host. - * - * @param hostHeaderValue the header value - * @return the determined host, or null if a host can't be determined - */ - public static String determineProxiedHost(final String hostHeaderValue) { - final String host; - // check for a port in the proxied host header - String[] hostSplits = hostHeaderValue == null ? new String[] {} : hostHeaderValue.split(":"); - if (hostSplits.length >= 1 && hostSplits.length <= 2) { - // zero or one occurrence of ':', this is an IPv4 address - // strip off the port by reassigning host the 0th split - host = hostSplits[0]; - } else if (hostSplits.length == 0) { - // hostHeaderValue passed in was null, no splits - host = null; - } else { - // hostHeaderValue has more than one occurrence of ":", IPv6 address - host = hostHeaderValue; - } - return host; - } - - /** - * Get Server Port based on Proxy Headers with fallback to HttpServletRequest.getServerPort() - * - * @param httpServletRequest HTTP Servlet Request - * @return Server port number - */ - public static int getServerPort(final HttpServletRequest httpServletRequest) { - final String port = determineProxiedPort(httpServletRequest); - try { - return Integer.parseInt(port); - } catch (final NumberFormatException e) { - return httpServletRequest.getServerPort(); - } - } - - /** - * Determines the port based on first considering proxy related headers and falling back to the port of the servlet request. - * - * @param httpServletRequest the request - * @return the determined port - */ - public static String determineProxiedPort(final HttpServletRequest httpServletRequest) { - final String hostHeaderValue = getFirstHeaderValue(httpServletRequest, PROXY_HOST_HTTP_HEADER, FORWARDED_HOST_HTTP_HEADER); - final String portHeaderValue = getFirstHeaderValue(httpServletRequest, PROXY_PORT_HTTP_HEADER, FORWARDED_PORT_HTTP_HEADER); - - final String proxiedPort = determineProxiedPort(hostHeaderValue, portHeaderValue); - return StringUtils.isBlank(proxiedPort) ? String.valueOf(httpServletRequest.getServerPort()) : proxiedPort; - } - - /** - * Determines the port based on the header values. The header values are intended to come from headers like X-ProxyHost/X-ProxyPort - * or X-Forwarded-Host/X-Forwarded-Port. - * - * @param hostHeaderValue the host header value - * @param portHeaderValue the host port value - * @return the determined port, or null if one can't be determined - */ - public static String determineProxiedPort(final String hostHeaderValue, final String portHeaderValue) { - final String port; - // check for a port in the proxied host header - String[] hostSplits = hostHeaderValue == null ? new String[] {} : hostHeaderValue.split(":"); - // determine the proxied port - final String portFromHostHeader; - if (hostSplits.length == 2) { - // if the port is specified in the proxied host header, it will be overridden by the - // port specified in X-ProxyPort or X-Forwarded-Port - portFromHostHeader = hostSplits[1]; - } else { - portFromHostHeader = null; - } - if (StringUtils.isNotBlank(portFromHostHeader) && StringUtils.isNotBlank(portHeaderValue)) { - logger.warn("Forwarded Host Port [{}] replaced with Forwarded Port [{}]", portFromHostHeader, portHeaderValue); - } - port = StringUtils.isNotBlank(portHeaderValue) ? portHeaderValue : (StringUtils.isNotBlank(portFromHostHeader) ? portFromHostHeader : null); - return port; - } -} diff --git a/nifi-commons/nifi-web-utils/src/test/java/org/apache/nifi/web/filter/SanitizeContextPathFilterTest.java b/nifi-commons/nifi-web-utils/src/test/java/org/apache/nifi/web/filter/SanitizeContextPathFilterTest.java deleted file mode 100644 index 6301252ca9b3..000000000000 --- a/nifi-commons/nifi-web-utils/src/test/java/org/apache/nifi/web/filter/SanitizeContextPathFilterTest.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * 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.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; -import org.mockito.stubbing.Answer; - -import jakarta.servlet.FilterConfig; -import jakarta.servlet.ServletContext; -import jakarta.servlet.ServletException; -import jakarta.servlet.http.HttpServletRequest; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.when; - -@ExtendWith(MockitoExtension.class) -public class SanitizeContextPathFilterTest { - @Test - public void testInitShouldExtractAllowedContextPaths(@Mock ServletContext servletContext, @Mock FilterConfig filterConfig) throws ServletException { - final String expectedAllowedContextPaths = String.join(",", new String[]{"/path1", "/path2"}); - final Map parameters = Collections.singletonMap("allowedContextPaths", expectedAllowedContextPaths); - when(servletContext.getInitParameter(anyString())).thenAnswer( - (Answer) invocation -> getValue(invocation.getArgument(0, String.class), parameters)); - when(filterConfig.getServletContext()).thenReturn(servletContext); - SanitizeContextPathFilter sanitizeContextPathFilter = new SanitizeContextPathFilter(); - sanitizeContextPathFilter.init(filterConfig); - - assertEquals(expectedAllowedContextPaths, sanitizeContextPathFilter.getAllowedContextPaths()); - } - - @Test - public void testInitShouldHandleBlankAllowedContextPaths(@Mock ServletContext servletContext, @Mock FilterConfig filterConfig) throws ServletException { - when(servletContext.getInitParameter(anyString())).thenReturn(""); - when(filterConfig.getServletContext()).thenReturn(servletContext); - SanitizeContextPathFilter sanitizeContextPathFilter = new SanitizeContextPathFilter(); - sanitizeContextPathFilter.init(filterConfig); - - assertEquals("", sanitizeContextPathFilter.getAllowedContextPaths()); - } - - @Test - public void testShouldInjectContextPathAttribute(@Mock ServletContext servletContext, @Mock FilterConfig filterConfig, - @Mock HttpServletRequest httpServletRequest) throws ServletException { - final String expectedAllowedContextPaths = String.join(",", new String[]{"/path1", "/path2"}); - final String expectedForwardPath = "index.jsp"; - final Map parameters = new HashMap<>(); - parameters.put("allowedContextPaths", expectedAllowedContextPaths); - parameters.put("forwardPath", expectedForwardPath); - final String expectedContextPath = "/path1"; - final Map headers = new HashMap<>(); - headers.put("X-ProxyContextPath", "path1"); - headers.put("X-Forwarded-Context", ""); - headers.put("X-Forwarded-Prefix", ""); - final Map requestAttributes = new HashMap<>(); - - when(servletContext.getInitParameter(anyString())).thenAnswer( - (Answer) invocation -> getValue(invocation.getArgument(0, String.class), parameters)); - when(filterConfig.getServletContext()).thenReturn(servletContext); - when(httpServletRequest.getHeader(anyString())).thenAnswer( - (Answer) invocation -> getValue(invocation.getArgument(0, String.class), headers)); - doAnswer((Answer) invocation -> { - requestAttributes.put(invocation.getArgument(0, String.class), invocation.getArgument(1, Object.class)); - return null; - }).when(httpServletRequest).setAttribute(anyString(), any()); - - SanitizeContextPathFilter sanitizeContextPathFilter = new SanitizeContextPathFilter(); - sanitizeContextPathFilter.init(filterConfig); - sanitizeContextPathFilter.injectContextPathAttribute(httpServletRequest); - - assertEquals(expectedContextPath, requestAttributes.get("contextPath")); - } - - private static String getValue(String parameterName, Map params) { - return params != null && params.containsKey(parameterName) ? params.get(parameterName) : ""; - } -} diff --git a/nifi-commons/nifi-web-utils/src/test/java/org/apache/nifi/web/util/WebUtilsTest.java b/nifi-commons/nifi-web-utils/src/test/java/org/apache/nifi/web/util/WebUtilsTest.java deleted file mode 100644 index 37a5a092faa3..000000000000 --- a/nifi-commons/nifi-web-utils/src/test/java/org/apache/nifi/web/util/WebUtilsTest.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * 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.util; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -import jakarta.servlet.http.HttpServletRequest; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.when; - -@ExtendWith(MockitoExtension.class) -public class WebUtilsTest { - - @Mock(strictness = Mock.Strictness.LENIENT) - private HttpServletRequest request; - - @Test - public void testDeterminedProxiedSchemeWhenNoHeaders() { - when(request.getHeader(any())).thenReturn(null); - when(request.getScheme()).thenReturn("https"); - assertEquals("https", WebUtils.determineProxiedScheme(request)); - } - - @Test - public void testDeterminedProxiedSchemeWhenXProxySchemeAvailable() { - when(request.getHeader(eq(WebUtils.PROXY_SCHEME_HTTP_HEADER))).thenReturn("http"); - assertEquals("http", WebUtils.determineProxiedScheme(request)); - } - - @Test - public void testDeterminedProxiedSchemeWhenXForwardedProtoAvailable() { - when(request.getHeader(eq(WebUtils.FORWARDED_PROTO_HTTP_HEADER))).thenReturn("http"); - assertEquals("http", WebUtils.determineProxiedScheme(request)); - } - - @Test - public void testDetermineProxiedHostWhenNoHeaders() { - when(request.getHeader(any())).thenReturn(null); - when(request.getServerName()).thenReturn("localhost"); - assertEquals("localhost", WebUtils.determineProxiedHost(request)); - } - - @Test - public void testDetermineProxiedHostWhenXProxyHostAvailable() { - when(request.getHeader(eq(WebUtils.PROXY_HOST_HTTP_HEADER))).thenReturn("x-proxy-host"); - assertEquals("x-proxy-host", WebUtils.determineProxiedHost(request)); - } - - @Test - public void testDetermineProxiedHostWhenXProxyHostAvailableWithPort() { - when(request.getHeader(eq(WebUtils.PROXY_HOST_HTTP_HEADER))).thenReturn("x-proxy-host:443"); - assertEquals("x-proxy-host", WebUtils.determineProxiedHost(request)); - } - - @Test - public void testDetermineProxiedHostWhenXForwardedHostAvailable() { - when(request.getHeader(eq(WebUtils.FORWARDED_HOST_HTTP_HEADER))).thenReturn("x-forwarded-host"); - assertEquals("x-forwarded-host", WebUtils.determineProxiedHost(request)); - } - - @Test - public void testDetermineProxiedHostWhenXForwardedHostAvailableWithPort() { - when(request.getHeader(eq(WebUtils.FORWARDED_HOST_HTTP_HEADER))).thenReturn("x-forwarded-host:443"); - assertEquals("x-forwarded-host", WebUtils.determineProxiedHost(request)); - } - - @Test - public void testDetermineProxiedPortWhenNoHeaders() { - when(request.getServerPort()).thenReturn(443); - assertEquals("443", WebUtils.determineProxiedPort(request)); - } - - @Test - public void testDetermineProxiedPortWhenXProxyPortAvailable() { - when(request.getHeader(eq(WebUtils.PROXY_HOST_HTTP_HEADER))).thenReturn("x-proxy-host"); - when(request.getHeader(eq(WebUtils.PROXY_PORT_HTTP_HEADER))).thenReturn("8443"); - assertEquals("8443", WebUtils.determineProxiedPort(request)); - } - - @Test - public void testDetermineProxiedPortWhenPortInXProxyHost() { - when(request.getHeader(eq(WebUtils.PROXY_HOST_HTTP_HEADER))).thenReturn("x-proxy-host:1234"); - assertEquals("1234", WebUtils.determineProxiedPort(request)); - } - - @Test - public void testDetermineProxiedPortWhenXProxyPortOverridesXProxy() { - when(request.getHeader(eq(WebUtils.PROXY_HOST_HTTP_HEADER))).thenReturn("x-proxy-host:1234"); - when(request.getHeader(eq(WebUtils.PROXY_PORT_HTTP_HEADER))).thenReturn("8443"); - assertEquals("8443", WebUtils.determineProxiedPort(request)); - } - - @Test - public void testDetermineProxiedPortWhenXForwardedPortAvailable() { - when(request.getHeader(eq(WebUtils.FORWARDED_HOST_HTTP_HEADER))).thenReturn("x-forwarded-host"); - when(request.getHeader(eq(WebUtils.FORWARDED_PORT_HTTP_HEADER))).thenReturn("8443"); - assertEquals("8443", WebUtils.determineProxiedPort(request)); - } - - @Test - public void testDetermineProxiedPortWhenPortInXForwardedHost() { - when(request.getHeader(eq(WebUtils.FORWARDED_HOST_HTTP_HEADER))).thenReturn("x-forwarded-host:1234"); - assertEquals("1234", WebUtils.determineProxiedPort(request)); - } - - @Test - public void testDetermineProxiedPortWhenXForwardedPortOverridesXForwardedHost() { - when(request.getHeader(eq(WebUtils.FORWARDED_HOST_HTTP_HEADER))).thenReturn("x-forwarded-host:1234"); - when(request.getHeader(eq(WebUtils.FORWARDED_PORT_HTTP_HEADER))).thenReturn("8443"); - assertEquals("8443", WebUtils.determineProxiedPort(request)); - } - -} diff --git a/nifi-commons/pom.xml b/nifi-commons/pom.xml index 1d8ed6d791a2..112e15b9db23 100644 --- a/nifi-commons/pom.xml +++ b/nifi-commons/pom.xml @@ -62,6 +62,7 @@ nifi-hashicorp-vault-api nifi-web-client nifi-web-client-api + nifi-web-servlet-shared nifi-web-utils nifi-write-ahead-log nifi-xml-processing diff --git a/nifi-extension-bundles/nifi-confluent-platform-bundle/nifi-confluent-schema-registry-service/src/main/java/org/apache/nifi/confluent/schemaregistry/client/RestSchemaRegistryClient.java b/nifi-extension-bundles/nifi-confluent-platform-bundle/nifi-confluent-schema-registry-service/src/main/java/org/apache/nifi/confluent/schemaregistry/client/RestSchemaRegistryClient.java index 80e2417768f6..55361b011742 100644 --- a/nifi-extension-bundles/nifi-confluent-platform-bundle/nifi-confluent-schema-registry-service/src/main/java/org/apache/nifi/confluent/schemaregistry/client/RestSchemaRegistryClient.java +++ b/nifi-extension-bundles/nifi-confluent-platform-bundle/nifi-confluent-schema-registry-service/src/main/java/org/apache/nifi/confluent/schemaregistry/client/RestSchemaRegistryClient.java @@ -25,7 +25,7 @@ import org.apache.nifi.schema.access.SchemaNotFoundException; import org.apache.nifi.serialization.record.RecordSchema; import org.apache.nifi.serialization.record.SchemaIdentifier; -import org.apache.nifi.web.util.WebUtils; +import org.apache.nifi.web.util.WebClientUtils; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ArrayNode; @@ -86,7 +86,7 @@ public RestSchemaRegistryClient(final List baseUrls, final ClientConfig clientConfig = new ClientConfig(); clientConfig.property(ClientProperties.CONNECT_TIMEOUT, timeoutMillis); clientConfig.property(ClientProperties.READ_TIMEOUT, timeoutMillis); - client = WebUtils.createClient(clientConfig, sslContext); + client = WebClientUtils.createClient(clientConfig, sslContext); if (StringUtils.isNoneBlank(username, password)) { client.register(HttpAuthenticationFeature.basic(username, password)); diff --git a/nifi-framework-bundle/nifi-framework-nar-bom/pom.xml b/nifi-framework-bundle/nifi-framework-nar-bom/pom.xml index 3aa2756dd602..771871833c36 100644 --- a/nifi-framework-bundle/nifi-framework-nar-bom/pom.xml +++ b/nifi-framework-bundle/nifi-framework-nar-bom/pom.xml @@ -201,6 +201,12 @@ 2.0.0-SNAPSHOT provided + + org.apache.nifi + nifi-web-servlet-shared + 2.0.0-SNAPSHOT + provided + org.apache.nifi nifi-web-utils diff --git a/nifi-framework-bundle/nifi-framework-nar/pom.xml b/nifi-framework-bundle/nifi-framework-nar/pom.xml index 19a6f2ba8eb6..593898903922 100644 --- a/nifi-framework-bundle/nifi-framework-nar/pom.xml +++ b/nifi-framework-bundle/nifi-framework-nar/pom.xml @@ -170,6 +170,11 @@ nifi-web-security compile + + org.apache.nifi + nifi-web-servlet-shared + compile + org.apache.nifi nifi-web-utils diff --git a/nifi-framework-bundle/nifi-framework/nifi-framework-components/src/main/java/org/apache/nifi/remote/RemoteNiFiUtils.java b/nifi-framework-bundle/nifi-framework/nifi-framework-components/src/main/java/org/apache/nifi/remote/RemoteNiFiUtils.java index f4715a643a05..8cb921e7693f 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-framework-components/src/main/java/org/apache/nifi/remote/RemoteNiFiUtils.java +++ b/nifi-framework-bundle/nifi-framework/nifi-framework-components/src/main/java/org/apache/nifi/remote/RemoteNiFiUtils.java @@ -16,7 +16,7 @@ */ package org.apache.nifi.remote; -import org.apache.nifi.web.util.WebUtils; +import org.apache.nifi.web.util.WebClientUtils; import org.glassfish.jersey.client.ClientConfig; import org.glassfish.jersey.client.ClientProperties; @@ -45,9 +45,9 @@ private Client getClient(final SSLContext sslContext) { final Client client; if (sslContext == null) { - client = WebUtils.createClient(clientConfig); + client = WebClientUtils.createClient(clientConfig); } else { - client = WebUtils.createClient(clientConfig, sslContext); + client = WebClientUtils.createClient(clientConfig, sslContext); } return client; diff --git a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/pom.xml b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/pom.xml index 340a979689bd..211488dcdc34 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/pom.xml +++ b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/pom.xml @@ -182,6 +182,11 @@ nifi-web-utils provided + + org.apache.nifi + nifi-web-servlet-shared + provided + org.apache.nifi nifi-site-to-site diff --git a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ApplicationResource.java b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ApplicationResource.java index 94444f72b188..13e7ca781866 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ApplicationResource.java +++ b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ApplicationResource.java @@ -63,8 +63,8 @@ import org.apache.nifi.web.api.entity.TransactionResultEntity; import org.apache.nifi.web.security.ProxiedEntitiesUtils; import org.apache.nifi.web.security.util.CacheKey; -import org.apache.nifi.web.util.RequestUriBuilder; -import org.apache.nifi.web.util.WebUtils; +import org.apache.nifi.web.servlet.shared.ProxyHeader; +import org.apache.nifi.web.servlet.shared.RequestUriBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -100,12 +100,6 @@ 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 static org.apache.nifi.web.util.WebUtils.FORWARDED_HOST_HTTP_HEADER; -import static org.apache.nifi.web.util.WebUtils.FORWARDED_PORT_HTTP_HEADER; -import static org.apache.nifi.web.util.WebUtils.FORWARDED_PROTO_HTTP_HEADER; -import static org.apache.nifi.web.util.WebUtils.PROXY_HOST_HTTP_HEADER; -import static org.apache.nifi.web.util.WebUtils.PROXY_PORT_HTTP_HEADER; -import static org.apache.nifi.web.util.WebUtils.PROXY_SCHEME_HTTP_HEADER; /** * Base class for controllers. @@ -300,21 +294,21 @@ protected Map getHeaders(final Map overriddenHea } // if the scheme is not set by the client, include the details from this request but don't override - final String proxyScheme = getFirstHeaderValue(PROXY_SCHEME_HTTP_HEADER, FORWARDED_PROTO_HTTP_HEADER); + final String proxyScheme = getFirstHeaderValue(ProxyHeader.PROXY_SCHEME.getHeader(), ProxyHeader.FORWARDED_PROTO.getHeader()); if (proxyScheme == null) { - result.put(PROXY_SCHEME_HTTP_HEADER, httpServletRequest.getScheme()); + result.put(ProxyHeader.PROXY_SCHEME.getHeader(), httpServletRequest.getScheme()); } // if the host is not set by the client, include the details from this request but don't override - final String proxyHost = getFirstHeaderValue(PROXY_HOST_HTTP_HEADER, FORWARDED_HOST_HTTP_HEADER); + final String proxyHost = getFirstHeaderValue(ProxyHeader.PROXY_HOST.getHeader(), ProxyHeader.FORWARDED_HOST.getHeader()); if (proxyHost == null) { - result.put(PROXY_HOST_HTTP_HEADER, httpServletRequest.getServerName()); + result.put(ProxyHeader.PROXY_HOST.getHeader(), httpServletRequest.getServerName()); } // if the port is not set by the client, include the details from this request but don't override - final String proxyPort = getFirstHeaderValue(PROXY_PORT_HTTP_HEADER, FORWARDED_PORT_HTTP_HEADER); + final String proxyPort = getFirstHeaderValue(ProxyHeader.PROXY_PORT.getHeader(), ProxyHeader.FORWARDED_PORT.getHeader()); if (proxyPort == null) { - result.put(PROXY_PORT_HTTP_HEADER, String.valueOf(httpServletRequest.getServerPort())); + result.put(ProxyHeader.PROXY_PORT.getHeader(), String.valueOf(httpServletRequest.getServerPort())); } return result; @@ -328,7 +322,19 @@ protected Map getHeaders(final Map overriddenHea * @return the value for the first key found */ private String getFirstHeaderValue(final String... keys) { - return WebUtils.getFirstHeaderValue(httpServletRequest, keys); + if (keys == null) { + return null; + } + + for (final String key : keys) { + final String value = httpServletRequest.getHeader(key); + + if (value != null) { + return value; + } + } + + return null; } /** diff --git a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/AuthenticationResource.java b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/AuthenticationResource.java index e65399496fe4..d3c60275afc6 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/AuthenticationResource.java +++ b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/AuthenticationResource.java @@ -34,7 +34,7 @@ import org.apache.nifi.web.api.dto.AuthenticationConfigurationDTO; import org.apache.nifi.web.api.entity.AuthenticationConfigurationEntity; import org.apache.nifi.web.configuration.AuthenticationConfiguration; -import org.apache.nifi.web.util.RequestUriBuilder; +import org.apache.nifi.web.servlet.shared.RequestUriBuilder; import org.springframework.stereotype.Controller; import org.springframework.util.StringUtils; diff --git a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/web/api/TestApplicationResource.java b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/web/api/TestApplicationResource.java index e116d883b098..036bade8b1bb 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/web/api/TestApplicationResource.java +++ b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/web/api/TestApplicationResource.java @@ -17,6 +17,7 @@ package org.apache.nifi.web.api; import org.apache.nifi.util.NiFiProperties; +import org.apache.nifi.web.servlet.shared.ProxyHeader; import org.glassfish.jersey.uri.internal.JerseyUriBuilder; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -27,7 +28,6 @@ import org.mockito.stubbing.Answer; import jakarta.servlet.http.HttpServletRequest; -import jakarta.ws.rs.core.UriBuilderException; import jakarta.ws.rs.core.UriInfo; import java.net.URI; import java.util.Arrays; @@ -35,15 +35,6 @@ import java.util.List; import java.util.Map; -import static org.apache.nifi.web.util.WebUtils.FORWARDED_CONTEXT_HTTP_HEADER; -import static org.apache.nifi.web.util.WebUtils.FORWARDED_HOST_HTTP_HEADER; -import static org.apache.nifi.web.util.WebUtils.FORWARDED_PORT_HTTP_HEADER; -import static org.apache.nifi.web.util.WebUtils.FORWARDED_PREFIX_HTTP_HEADER; -import static org.apache.nifi.web.util.WebUtils.FORWARDED_PROTO_HTTP_HEADER; -import static org.apache.nifi.web.util.WebUtils.PROXY_CONTEXT_PATH_HTTP_HEADER; -import static org.apache.nifi.web.util.WebUtils.PROXY_HOST_HTTP_HEADER; -import static org.apache.nifi.web.util.WebUtils.PROXY_PORT_HTTP_HEADER; -import static org.apache.nifi.web.util.WebUtils.PROXY_SCHEME_HTTP_HEADER; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.ArgumentMatchers.anyString; @@ -78,7 +69,7 @@ public void setUp(@Mock UriInfo uriInfo) throws Exception { @Test public void testGenerateUriShouldBlockProxyContextPathHeaderIfNotInAllowList() { when(request.getHeader(anyString())).thenAnswer(new RequestAnswer()); - assertThrows(UriBuilderException.class, () -> resource.generateResourceUri(ACTUAL_RESOURCE)); + assertThrows(IllegalArgumentException.class, () -> resource.generateResourceUri(ACTUAL_RESOURCE)); } @Test @@ -99,19 +90,19 @@ public void testGenerateUriShouldAllowProxyContextPathHeaderIfElementInMultipleA @Test public void testGenerateUriShouldBlockForwardedContextHeaderIfNotInAllowList() { - when(request.getHeader(anyString())).thenAnswer(new RequestAnswer(FORWARDED_CONTEXT_HTTP_HEADER)); - assertThrows(UriBuilderException.class, () -> resource.generateResourceUri(ACTUAL_RESOURCE)); + when(request.getHeader(anyString())).thenAnswer(new RequestAnswer(ProxyHeader.FORWARDED_CONTEXT.getHeader())); + assertThrows(IllegalArgumentException.class, () -> resource.generateResourceUri(ACTUAL_RESOURCE)); } @Test public void testGenerateUriShouldBlockForwardedPrefixHeaderIfNotInAllowList() { - when(request.getHeader(anyString())).thenAnswer(new RequestAnswer(FORWARDED_PREFIX_HTTP_HEADER)); - assertThrows(UriBuilderException.class, () -> resource.generateResourceUri(ACTUAL_RESOURCE)); + when(request.getHeader(anyString())).thenAnswer(new RequestAnswer(ProxyHeader.FORWARDED_PREFIX.getHeader())); + assertThrows(IllegalArgumentException.class, () -> resource.generateResourceUri(ACTUAL_RESOURCE)); } @Test public void testGenerateUriShouldAllowForwardedContextHeaderIfInAllowList() { - when(request.getHeader(anyString())).thenAnswer(new RequestAnswer(FORWARDED_CONTEXT_HTTP_HEADER)); + when(request.getHeader(anyString())).thenAnswer(new RequestAnswer(ProxyHeader.FORWARDED_CONTEXT.getHeader())); setNiFiProperties(Collections.singletonMap(PROXY_CONTEXT_PATH_PROP, ALLOWED_PATH)); assertEquals(EXPECTED_URI, resource.generateResourceUri(ACTUAL_RESOURCE)); @@ -119,7 +110,7 @@ public void testGenerateUriShouldAllowForwardedContextHeaderIfInAllowList() { @Test public void testGenerateUriShouldAllowForwardedPrefixHeaderIfInAllowList() { - when(request.getHeader(anyString())).thenAnswer(new RequestAnswer(FORWARDED_PREFIX_HTTP_HEADER)); + when(request.getHeader(anyString())).thenAnswer(new RequestAnswer(ProxyHeader.FORWARDED_PREFIX.getHeader())); setNiFiProperties(Collections.singletonMap(PROXY_CONTEXT_PATH_PROP, ALLOWED_PATH)); assertEquals(EXPECTED_URI, resource.generateResourceUri(ACTUAL_RESOURCE)); @@ -127,7 +118,7 @@ public void testGenerateUriShouldAllowForwardedPrefixHeaderIfInAllowList() { @Test public void testGenerateUriShouldAllowForwardedContextHeaderIfElementInMultipleAllowList() { - when(request.getHeader(anyString())).thenAnswer(new RequestAnswer(FORWARDED_CONTEXT_HTTP_HEADER)); + when(request.getHeader(anyString())).thenAnswer(new RequestAnswer(ProxyHeader.FORWARDED_CONTEXT.getHeader())); setNiFiProperties(Collections.singletonMap(PROXY_CONTEXT_PATH_PROP, MULTIPLE_ALLOWED_PATHS)); assertEquals(EXPECTED_URI, resource.generateResourceUri(ACTUAL_RESOURCE)); @@ -135,7 +126,7 @@ public void testGenerateUriShouldAllowForwardedContextHeaderIfElementInMultipleA @Test public void testGenerateUriShouldAllowForwardedPrefixHeaderIfElementInMultipleAllowList() { - when(request.getHeader(anyString())).thenAnswer(new RequestAnswer(FORWARDED_PREFIX_HTTP_HEADER)); + when(request.getHeader(anyString())).thenAnswer(new RequestAnswer(ProxyHeader.FORWARDED_PREFIX.getHeader())); setNiFiProperties(Collections.singletonMap(PROXY_CONTEXT_PATH_PROP, MULTIPLE_ALLOWED_PATHS)); assertEquals(EXPECTED_URI, resource.generateResourceUri(ACTUAL_RESOURCE)); @@ -159,7 +150,7 @@ private static class RequestAnswer implements Answer { private final List proxyHeaders; public RequestAnswer() { - this(FORWARDED_PREFIX_HTTP_HEADER, FORWARDED_CONTEXT_HTTP_HEADER, PROXY_CONTEXT_PATH_HTTP_HEADER); + this(ProxyHeader.FORWARDED_PREFIX.getHeader(), ProxyHeader.FORWARDED_CONTEXT.getHeader(), ProxyHeader.PROXY_CONTEXT_PATH.getHeader()); } public RequestAnswer(String... proxyHeaders) { @@ -175,11 +166,11 @@ public String answer(InvocationOnMock invocationOnMock) { String argument = invocationOnMock.getArgument(0); if (proxyHeaders.contains(argument)) { return ALLOWED_PATH; - } else if (Arrays.asList(FORWARDED_PORT_HTTP_HEADER, PROXY_PORT_HTTP_HEADER).contains(argument)) { + } else if (Arrays.asList(ProxyHeader.FORWARDED_PORT.getHeader(), ProxyHeader.FORWARDED_PREFIX.getHeader()).contains(argument)) { return "8081"; - } else if (Arrays.asList(FORWARDED_PROTO_HTTP_HEADER, PROXY_SCHEME_HTTP_HEADER).contains(argument)) { + } else if (Arrays.asList(ProxyHeader.FORWARDED_PROTO.getHeader(), ProxyHeader.PROXY_SCHEME.getHeader()).contains(argument)) { return "https"; - } else if (Arrays.asList(PROXY_HOST_HTTP_HEADER, FORWARDED_HOST_HTTP_HEADER).contains(argument)) { + } else if (Arrays.asList(ProxyHeader.PROXY_HOST.getHeader(), ProxyHeader.FORWARDED_HOST.getHeader()).contains(argument)) { return "nifi.apache.org:8081"; } else { return ""; diff --git a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/web/api/TestDataTransferResource.java b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/web/api/TestDataTransferResource.java index b823fa048b6c..af1eec32259e 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/web/api/TestDataTransferResource.java +++ b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/web/api/TestDataTransferResource.java @@ -30,6 +30,7 @@ import org.apache.nifi.util.NiFiProperties; import org.apache.nifi.web.NiFiServiceFacade; import org.apache.nifi.web.api.entity.TransactionResultEntity; +import org.apache.nifi.web.servlet.shared.ProxyHeader; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; @@ -46,9 +47,6 @@ import java.net.URISyntaxException; import java.net.URL; -import static org.apache.nifi.web.util.WebUtils.PROXY_HOST_HTTP_HEADER; -import static org.apache.nifi.web.util.WebUtils.PROXY_PORT_HTTP_HEADER; -import static org.apache.nifi.web.util.WebUtils.PROXY_SCHEME_HTTP_HEADER; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.any; @@ -204,9 +202,9 @@ public void testCreateTransactionThroughReverseProxy() throws Exception { uriInfoField.set(resource, uriInfo); final HttpServletRequest request = mock(HttpServletRequest.class); - when(request.getHeader(PROXY_SCHEME_HTTP_HEADER)).thenReturn("https"); - when(request.getHeader(PROXY_HOST_HTTP_HEADER)).thenReturn("nifi2.example.com"); - when(request.getHeader(PROXY_PORT_HTTP_HEADER)).thenReturn("443"); + when(request.getHeader(ProxyHeader.PROXY_SCHEME.getHeader())).thenReturn("https"); + when(request.getHeader(ProxyHeader.PROXY_HOST.getHeader())).thenReturn("nifi2.example.com"); + when(request.getHeader(ProxyHeader.PROXY_PORT.getHeader())).thenReturn("443"); final Field httpServletRequestField = resource.getClass().getSuperclass().getSuperclass() .getDeclaredField("httpServletRequest"); httpServletRequestField.setAccessible(true); diff --git a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/pom.xml b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/pom.xml index 8f1f9b2991a4..05affc9d8fd7 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/pom.xml +++ b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/pom.xml @@ -91,6 +91,11 @@ org.apache.nifi nifi-framework-api + + org.apache.nifi + nifi-web-servlet-shared + 2.0.0-SNAPSHOT + org.apache.nifi nifi-web-utils diff --git a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/StandardAuthenticationEntryPoint.java b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/StandardAuthenticationEntryPoint.java index 7398f2fd0837..ad218c5fedea 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/StandardAuthenticationEntryPoint.java +++ b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/StandardAuthenticationEntryPoint.java @@ -19,7 +19,7 @@ import org.apache.nifi.web.security.cookie.ApplicationCookieName; import org.apache.nifi.web.security.cookie.ApplicationCookieService; import org.apache.nifi.web.security.cookie.StandardApplicationCookieService; -import org.apache.nifi.web.util.RequestUriBuilder; +import org.apache.nifi.web.servlet.shared.RequestUriBuilder; import org.springframework.http.MediaType; import org.springframework.security.core.AuthenticationException; import org.springframework.security.oauth2.core.OAuth2AuthenticationException; diff --git a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/csrf/StandardCookieCsrfTokenRepository.java b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/csrf/StandardCookieCsrfTokenRepository.java index f98da7f9fd69..8ced8103ff66 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/csrf/StandardCookieCsrfTokenRepository.java +++ b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/csrf/StandardCookieCsrfTokenRepository.java @@ -21,7 +21,7 @@ import org.apache.nifi.web.security.cookie.StandardApplicationCookieService; import org.apache.nifi.web.security.http.SecurityCookieName; import org.apache.nifi.web.security.http.SecurityHeader; -import org.apache.nifi.web.util.RequestUriBuilder; +import org.apache.nifi.web.servlet.shared.RequestUriBuilder; import org.springframework.http.ResponseCookie; import org.springframework.security.web.csrf.CsrfToken; import org.springframework.security.web.csrf.CsrfTokenRepository; diff --git a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/oidc/client/web/OidcBearerTokenRefreshFilter.java b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/oidc/client/web/OidcBearerTokenRefreshFilter.java index 9b322a7aee51..c8e2fba264f5 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/oidc/client/web/OidcBearerTokenRefreshFilter.java +++ b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/oidc/client/web/OidcBearerTokenRefreshFilter.java @@ -24,7 +24,7 @@ import org.apache.nifi.web.security.jwt.provider.BearerTokenProvider; import org.apache.nifi.web.security.jwt.provider.SupportedClaim; import org.apache.nifi.web.security.token.LoginAuthenticationToken; -import org.apache.nifi.web.util.RequestUriBuilder; +import org.apache.nifi.web.servlet.shared.RequestUriBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.security.core.Authentication; diff --git a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/oidc/client/web/StandardAuthorizationRequestRepository.java b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/oidc/client/web/StandardAuthorizationRequestRepository.java index bfb40de2c0f6..b10b4fff875e 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/oidc/client/web/StandardAuthorizationRequestRepository.java +++ b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/oidc/client/web/StandardAuthorizationRequestRepository.java @@ -19,7 +19,7 @@ import org.apache.nifi.web.security.cookie.ApplicationCookieName; import org.apache.nifi.web.security.cookie.ApplicationCookieService; import org.apache.nifi.web.security.cookie.StandardApplicationCookieService; -import org.apache.nifi.web.util.RequestUriBuilder; +import org.apache.nifi.web.servlet.shared.RequestUriBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.cache.Cache; diff --git a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/oidc/client/web/StandardOAuth2AuthorizationRequestResolver.java b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/oidc/client/web/StandardOAuth2AuthorizationRequestResolver.java index 39c397e20d27..ff687fab7fd4 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/oidc/client/web/StandardOAuth2AuthorizationRequestResolver.java +++ b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/oidc/client/web/StandardOAuth2AuthorizationRequestResolver.java @@ -16,7 +16,7 @@ */ package org.apache.nifi.web.security.oidc.client.web; -import org.apache.nifi.web.util.RequestUriBuilder; +import org.apache.nifi.web.servlet.shared.RequestUriBuilder; import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository; import org.springframework.security.oauth2.client.web.DefaultOAuth2AuthorizationRequestResolver; import org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestCustomizers; diff --git a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/oidc/logout/OidcLogoutSuccessHandler.java b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/oidc/logout/OidcLogoutSuccessHandler.java index 91daf01cbff8..fd58d26e579a 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/oidc/logout/OidcLogoutSuccessHandler.java +++ b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/oidc/logout/OidcLogoutSuccessHandler.java @@ -28,7 +28,7 @@ import org.apache.nifi.web.security.oidc.revocation.TokenRevocationResponseClient; import org.apache.nifi.web.security.oidc.revocation.TokenTypeHint; import org.apache.nifi.web.security.token.LogoutAuthenticationToken; -import org.apache.nifi.web.util.RequestUriBuilder; +import org.apache.nifi.web.servlet.shared.RequestUriBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.security.core.Authentication; diff --git a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/oidc/web/authentication/OidcAuthenticationSuccessHandler.java b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/oidc/web/authentication/OidcAuthenticationSuccessHandler.java index ab6bcb64dca2..32d5f56a41d7 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/oidc/web/authentication/OidcAuthenticationSuccessHandler.java +++ b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/oidc/web/authentication/OidcAuthenticationSuccessHandler.java @@ -24,7 +24,7 @@ import org.apache.nifi.web.security.jwt.provider.BearerTokenProvider; import org.apache.nifi.web.security.oidc.OidcConfigurationException; import org.apache.nifi.web.security.token.LoginAuthenticationToken; -import org.apache.nifi.web.util.RequestUriBuilder; +import org.apache.nifi.web.servlet.shared.RequestUriBuilder; import org.springframework.security.core.Authentication; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; diff --git a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/saml2/service/web/StandardRelyingPartyRegistrationResolver.java b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/saml2/service/web/StandardRelyingPartyRegistrationResolver.java index e6f37f8bc2d3..33e729715fb3 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/saml2/service/web/StandardRelyingPartyRegistrationResolver.java +++ b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/saml2/service/web/StandardRelyingPartyRegistrationResolver.java @@ -17,7 +17,7 @@ package org.apache.nifi.web.security.saml2.service.web; import org.apache.nifi.web.security.saml2.registration.Saml2RegistrationProperty; -import org.apache.nifi.web.util.RequestUriBuilder; +import org.apache.nifi.web.servlet.shared.RequestUriBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.core.convert.converter.Converter; diff --git a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/saml2/service/web/StandardSaml2AuthenticationRequestRepository.java b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/saml2/service/web/StandardSaml2AuthenticationRequestRepository.java index 5abfc4859198..37fc83711097 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/saml2/service/web/StandardSaml2AuthenticationRequestRepository.java +++ b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/saml2/service/web/StandardSaml2AuthenticationRequestRepository.java @@ -19,7 +19,7 @@ import org.apache.nifi.web.security.cookie.ApplicationCookieName; import org.apache.nifi.web.security.cookie.ApplicationCookieService; import org.apache.nifi.web.security.cookie.StandardApplicationCookieService; -import org.apache.nifi.web.util.RequestUriBuilder; +import org.apache.nifi.web.servlet.shared.RequestUriBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.cache.Cache; diff --git a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/saml2/web/authentication/Saml2AuthenticationSuccessHandler.java b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/saml2/web/authentication/Saml2AuthenticationSuccessHandler.java index e6844485d3db..96fcd5325d8c 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/saml2/web/authentication/Saml2AuthenticationSuccessHandler.java +++ b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/saml2/web/authentication/Saml2AuthenticationSuccessHandler.java @@ -23,7 +23,7 @@ import org.apache.nifi.web.security.cookie.StandardApplicationCookieService; import org.apache.nifi.web.security.jwt.provider.BearerTokenProvider; import org.apache.nifi.web.security.token.LoginAuthenticationToken; -import org.apache.nifi.web.util.RequestUriBuilder; +import org.apache.nifi.web.servlet.shared.RequestUriBuilder; import org.springframework.core.convert.converter.Converter; import org.springframework.security.core.Authentication; import org.springframework.security.core.GrantedAuthority; diff --git a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/saml2/web/authentication/logout/Saml2LogoutSuccessHandler.java b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/saml2/web/authentication/logout/Saml2LogoutSuccessHandler.java index a77317e0a9e0..4d974cfbebe3 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/saml2/web/authentication/logout/Saml2LogoutSuccessHandler.java +++ b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/saml2/web/authentication/logout/Saml2LogoutSuccessHandler.java @@ -21,7 +21,7 @@ import org.apache.nifi.web.security.cookie.StandardApplicationCookieService; import org.apache.nifi.web.security.logout.LogoutRequest; import org.apache.nifi.web.security.logout.LogoutRequestManager; -import org.apache.nifi.web.util.RequestUriBuilder; +import org.apache.nifi.web.servlet.shared.RequestUriBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.security.core.Authentication; diff --git a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/saml2/web/authentication/logout/StandardSaml2LogoutRequestRepository.java b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/saml2/web/authentication/logout/StandardSaml2LogoutRequestRepository.java index e6e1bcaedb9c..eb2c79c30d9c 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/saml2/web/authentication/logout/StandardSaml2LogoutRequestRepository.java +++ b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/saml2/web/authentication/logout/StandardSaml2LogoutRequestRepository.java @@ -19,7 +19,7 @@ import org.apache.nifi.web.security.cookie.ApplicationCookieName; import org.apache.nifi.web.security.cookie.ApplicationCookieService; import org.apache.nifi.web.security.cookie.StandardApplicationCookieService; -import org.apache.nifi.web.util.RequestUriBuilder; +import org.apache.nifi.web.servlet.shared.RequestUriBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.cache.Cache; diff --git a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/x509/ocsp/OcspCertificateValidator.java b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/x509/ocsp/OcspCertificateValidator.java index c6aba94c0005..5ede7451b93a 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/x509/ocsp/OcspCertificateValidator.java +++ b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/main/java/org/apache/nifi/web/security/x509/ocsp/OcspCertificateValidator.java @@ -45,7 +45,7 @@ import org.apache.nifi.util.NiFiProperties; import org.apache.nifi.web.security.x509.ocsp.OcspStatus.ValidationStatus; import org.apache.nifi.web.security.x509.ocsp.OcspStatus.VerificationStatus; -import org.apache.nifi.web.util.WebUtils; +import org.apache.nifi.web.util.WebClientUtils; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.ocsp.OCSPObjectIdentifiers; import org.bouncycastle.asn1.x509.Extension; @@ -101,7 +101,7 @@ public OcspCertificateValidator(final NiFiProperties properties) { clientConfig.property(ClientProperties.CONNECT_TIMEOUT, CONNECT_TIMEOUT); // initialize the client - client = WebUtils.createClient(clientConfig); + client = WebClientUtils.createClient(clientConfig); // get the trusted CAs trustedCAs = getTrustedCAs(properties); diff --git a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/test/java/org/apache/nifi/web/security/StandardAuthenticationEntryPointTest.java b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/test/java/org/apache/nifi/web/security/StandardAuthenticationEntryPointTest.java index 0e0ccc5e4e66..7bb3732c2a28 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/test/java/org/apache/nifi/web/security/StandardAuthenticationEntryPointTest.java +++ b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/test/java/org/apache/nifi/web/security/StandardAuthenticationEntryPointTest.java @@ -17,7 +17,7 @@ package org.apache.nifi.web.security; import org.apache.nifi.web.security.cookie.ApplicationCookieName; -import org.apache.nifi.web.util.WebUtils; +import org.apache.nifi.web.servlet.shared.ProxyHeader; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.mock.web.MockHttpServletRequest; @@ -142,7 +142,7 @@ void testCommenceRemoveCookieForwardedPath() throws IOException { final ServletContext servletContext = request.getServletContext(); servletContext.setInitParameter(ALLOWED_CONTEXT_PATHS_PARAMETER, FORWARDED_PATH); - request.addHeader(WebUtils.FORWARDED_PREFIX_HTTP_HEADER, FORWARDED_PATH); + request.addHeader(ProxyHeader.FORWARDED_PREFIX.getHeader(), FORWARDED_PATH); final Cookie cookie = new Cookie(ApplicationCookieName.AUTHORIZATION_BEARER.getCookieName(), BEARER_TOKEN); request.setCookies(cookie); diff --git a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/test/java/org/apache/nifi/web/security/csrf/StandardCookieCsrfTokenRepositoryTest.java b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/test/java/org/apache/nifi/web/security/csrf/StandardCookieCsrfTokenRepositoryTest.java index 14173e28cc80..878e7ea5a9a2 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/test/java/org/apache/nifi/web/security/csrf/StandardCookieCsrfTokenRepositoryTest.java +++ b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/test/java/org/apache/nifi/web/security/csrf/StandardCookieCsrfTokenRepositoryTest.java @@ -17,7 +17,7 @@ package org.apache.nifi.web.security.csrf; import org.apache.nifi.web.security.http.SecurityCookieName; -import org.apache.nifi.web.util.WebUtils; +import org.apache.nifi.web.servlet.shared.ProxyHeader; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.mock.web.MockHttpServletRequest; @@ -125,10 +125,11 @@ public void testSaveTokenProxyContextPath() { final CsrfToken csrfToken = repository.generateToken(request); - request.addHeader(WebUtils.PROXY_SCHEME_HTTP_HEADER, HTTPS); - request.addHeader(WebUtils.PROXY_HOST_HTTP_HEADER, HOST); - request.addHeader(WebUtils.PROXY_PORT_HTTP_HEADER, PORT); - request.addHeader(WebUtils.PROXY_CONTEXT_PATH_HTTP_HEADER, CONTEXT_PATH); + request.addHeader(ProxyHeader.PROXY_SCHEME.getHeader(), HTTPS); + request.addHeader(ProxyHeader.PROXY_HOST.getHeader(), HOST); + request.addHeader(ProxyHeader.PROXY_PORT.getHeader(), PORT); + request.addHeader(ProxyHeader.PROXY_PORT.getHeader(), PORT); + request.addHeader(ProxyHeader.PROXY_CONTEXT_PATH.getHeader(), CONTEXT_PATH); final MockServletContext servletContext = (MockServletContext) request.getServletContext(); servletContext.setInitParameter(ALLOWED_CONTEXT_PATHS_PARAMETER, CONTEXT_PATH); diff --git a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/test/java/org/apache/nifi/web/security/oidc/client/web/StandardOAuth2AuthorizationRequestResolverTest.java b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/test/java/org/apache/nifi/web/security/oidc/client/web/StandardOAuth2AuthorizationRequestResolverTest.java index 6b36272318eb..e75f0e9a16ce 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/test/java/org/apache/nifi/web/security/oidc/client/web/StandardOAuth2AuthorizationRequestResolverTest.java +++ b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/test/java/org/apache/nifi/web/security/oidc/client/web/StandardOAuth2AuthorizationRequestResolverTest.java @@ -16,7 +16,7 @@ */ package org.apache.nifi.web.security.oidc.client.web; -import org.apache.nifi.web.util.WebUtils; +import org.apache.nifi.web.servlet.shared.ProxyHeader; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -60,6 +60,8 @@ class StandardOAuth2AuthorizationRequestResolverTest { private static final String REGISTRATION_ID = OidcRegistrationProperty.REGISTRATION_ID.getProperty(); + private static final int UNSPECIFIED_PORT = -1; + MockHttpServletRequest httpServletRequest; MockHttpServletResponse httpServletResponse; @@ -115,10 +117,11 @@ void testResolveFoundRedirectUriProxyHeaders() { servletContext.setInitParameter(ALLOWED_CONTEXT_PATHS_PARAMETER, FORWARDED_PATH); final URI forwardedRedirectUri = URI.create(FORWARDED_REDIRECT_URI); - httpServletRequest.addHeader(WebUtils.PROXY_SCHEME_HTTP_HEADER, forwardedRedirectUri.getScheme()); - httpServletRequest.addHeader(WebUtils.PROXY_HOST_HTTP_HEADER, forwardedRedirectUri.getHost()); - httpServletRequest.addHeader(WebUtils.PROXY_PORT_HTTP_HEADER, forwardedRedirectUri.getPort()); - httpServletRequest.addHeader(WebUtils.PROXY_CONTEXT_PATH_HTTP_HEADER, FORWARDED_PATH); + httpServletRequest.setServerPort(UNSPECIFIED_PORT); + httpServletRequest.addHeader(ProxyHeader.PROXY_SCHEME.getHeader(), forwardedRedirectUri.getScheme()); + httpServletRequest.addHeader(ProxyHeader.PROXY_HOST.getHeader(), forwardedRedirectUri.getHost()); + httpServletRequest.addHeader(ProxyHeader.PROXY_PORT.getHeader(), forwardedRedirectUri.getPort()); + httpServletRequest.addHeader(ProxyHeader.PROXY_CONTEXT_PATH.getHeader(), FORWARDED_PATH); final OAuth2AuthorizationRequest authorizationRequest = resolver.resolve(httpServletRequest, REGISTRATION_ID); diff --git a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/test/java/org/apache/nifi/web/security/oidc/web/authentication/OidcAuthenticationSuccessHandlerTest.java b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/test/java/org/apache/nifi/web/security/oidc/web/authentication/OidcAuthenticationSuccessHandlerTest.java index ba5784d833f0..bd8a51d9fc6e 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/test/java/org/apache/nifi/web/security/oidc/web/authentication/OidcAuthenticationSuccessHandlerTest.java +++ b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/test/java/org/apache/nifi/web/security/oidc/web/authentication/OidcAuthenticationSuccessHandlerTest.java @@ -22,7 +22,7 @@ import org.apache.nifi.web.security.oidc.client.web.OidcRegistrationProperty; import org.apache.nifi.web.security.oidc.client.web.converter.StandardOAuth2AuthenticationToken; import org.apache.nifi.web.security.token.LoginAuthenticationToken; -import org.apache.nifi.web.util.WebUtils; +import org.apache.nifi.web.servlet.shared.ProxyHeader; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -151,7 +151,7 @@ void testDetermineTargetUrl() { void testDetermineTargetUrlForwardedPath() { final ServletContext servletContext = httpServletRequest.getServletContext(); servletContext.setInitParameter(ALLOWED_CONTEXT_PATHS_PARAMETER, FORWARDED_PATH); - httpServletRequest.addHeader(WebUtils.FORWARDED_PREFIX_HTTP_HEADER, FORWARDED_PATH); + httpServletRequest.addHeader(ProxyHeader.FORWARDED_PREFIX.getHeader(), FORWARDED_PATH); httpServletRequest.setRequestURI(REQUEST_URI); diff --git a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/test/java/org/apache/nifi/web/security/saml2/service/web/StandardRelyingPartyRegistrationResolverTest.java b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/test/java/org/apache/nifi/web/security/saml2/service/web/StandardRelyingPartyRegistrationResolverTest.java index dd720bf0a8ae..989552505ad3 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/test/java/org/apache/nifi/web/security/saml2/service/web/StandardRelyingPartyRegistrationResolverTest.java +++ b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/test/java/org/apache/nifi/web/security/saml2/service/web/StandardRelyingPartyRegistrationResolverTest.java @@ -17,7 +17,7 @@ package org.apache.nifi.web.security.saml2.service.web; import org.apache.nifi.web.security.saml2.registration.Saml2RegistrationProperty; -import org.apache.nifi.web.util.WebUtils; +import org.apache.nifi.web.servlet.shared.ProxyHeader; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -100,7 +100,7 @@ void testResolveSingleLogoutForwardedPathFound() { final RelyingPartyRegistration registration = getSingleLogoutRegistration(); when(repository.findByRegistrationId(eq(REGISTRATION_ID))).thenReturn(registration); - request.addHeader(WebUtils.PROXY_CONTEXT_PATH_HTTP_HEADER, FORWARDED_PATH); + request.addHeader(ProxyHeader.PROXY_CONTEXT_PATH.getHeader(), FORWARDED_PATH); final RelyingPartyRegistration resolved = resolver.resolve(request, REGISTRATION_ID); diff --git a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/test/java/org/apache/nifi/web/security/saml2/web/authentication/Saml2AuthenticationSuccessHandlerTest.java b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/test/java/org/apache/nifi/web/security/saml2/web/authentication/Saml2AuthenticationSuccessHandlerTest.java index a3032cd6c5ad..11215abdcd56 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/test/java/org/apache/nifi/web/security/saml2/web/authentication/Saml2AuthenticationSuccessHandlerTest.java +++ b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-security/src/test/java/org/apache/nifi/web/security/saml2/web/authentication/Saml2AuthenticationSuccessHandlerTest.java @@ -19,7 +19,7 @@ import org.apache.nifi.authorization.util.IdentityMapping; import org.apache.nifi.web.security.cookie.ApplicationCookieName; import org.apache.nifi.web.security.jwt.provider.BearerTokenProvider; -import org.apache.nifi.web.util.WebUtils; +import org.apache.nifi.web.servlet.shared.ProxyHeader; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -120,7 +120,7 @@ void testDetermineTargetUrl() { void testDetermineTargetUrlForwardedPath() { final ServletContext servletContext = httpServletRequest.getServletContext(); servletContext.setInitParameter(ALLOWED_CONTEXT_PATHS_PARAMETER, FORWARDED_PATH); - httpServletRequest.addHeader(WebUtils.FORWARDED_PREFIX_HTTP_HEADER, FORWARDED_PATH); + httpServletRequest.addHeader(ProxyHeader.FORWARDED_PREFIX.getHeader(), FORWARDED_PATH); httpServletRequest.setRequestURI(REQUEST_URI);