From ebd5d3c68770fb2e604b3e39290625af2ba9d0f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sandeep=20More=CC=81?= Date: Thu, 20 Nov 2025 15:35:15 -0500 Subject: [PATCH 1/4] Update Knox to JDK 17 --- .github/workflows/main.yml | 2 +- .../resources/build-tools/pmd/pmd-ruleset.xml | 54 +- gateway-demo-ldap/pom.xml | 41 + gateway-openapi-ui/pom.xml | 11 + gateway-performance-test/pom.xml | 6 +- .../pom.xml | 9 + .../AbstractIdentityAssertionFilter.java | 3 + .../filter/CommonIdentityAssertionFilter.java | 2 + .../pom.xml | 9 +- gateway-provider-jersey/pom.xml | 9 + .../jersey/KnoxFilterUrlMappingsProvider.java | 38 + ...rsey.servlet.spi.FilterUrlMappingsProvider | 19 + gateway-provider-rewrite-common/pom.xml | 4 + .../api/UrlRewriteFilterDescriptor.java | 2 +- .../UrlRewriteFunctionDescriptorFactory.java | 5 +- .../api/UrlRewriteStepDescriptorFactory.java | 5 +- .../impl/UrlRewriteFilterDescriptorImpl.java | 4 +- .../pom.xml | 1 + .../pom.xml | 2 + .../pom.xml | 20 +- .../pom.xml | 10 + .../pom.xml | 17 +- gateway-provider-rewrite/pom.xml | 52 +- .../rewrite/api/UrlRewriteServletFilter.java | 2 +- .../api/UrlRewriteStreamFilterFactory.java | 4 +- .../UrlRewriteFunctionProcessorFactory.java | 5 +- .../rewrite/impl/UrlRewriteRequest.java | 2 +- .../rewrite/impl/UrlRewriteResponse.java | 2 +- .../impl/UrlRewriteStepProcessorFactory.java | 5 +- .../filter/rewrite/impl/UrlRewriteUtil.java | 2 +- .../gateway/filter/RemoteAuthFilterTest.java | 4 +- .../clientcert/filter/ClientCertFilter.java | 4 +- gateway-provider-security-hadoopauth/pom.xml | 34 +- .../filter/HadoopAuthFilterTest.java | 2 + gateway-provider-security-jwt/pom.xml | 12 + .../filter/JWTAccessTokenAssertionFilter.java | 2 + .../filter/JWTAuthCodeAssertionFilter.java | 2 + .../federation/AbstractJWTFilterTest.java | 2 + .../federation/CommonJWTFilterTest.java | 2 + gateway-provider-security-pac4j/pom.xml | 6 + gateway-provider-security-shiro/pom.xml | 32 +- gateway-provider-security-webappsec/pom.xml | 1 + .../home/bin/knox-functions.sh | 2 +- gateway-release/pom.xml | 35 + gateway-server/pom.xml | 81 +- .../apache/knox/gateway/GatewayFilter.java | 2 +- .../gateway/deploy/DeploymentFactory.java | 12 +- .../ApplicationDeploymentContributor.java | 6 +- .../apache/knox/gateway/model/Topology.java | 10 +- .../factory/AbstractServiceFactory.java | 6 +- .../DefaultServiceDefinitionRegistry.java | 6 +- .../impl/DefaultServiceRegistryService.java | 5 +- .../impl/ZookeeperTokenStateService.java | 23 +- .../topology/impl/DefaultTopologyService.java | 19 +- .../org/apache/knox/gateway/util/KnoxCLI.java | 2 +- .../util/ServiceDefinitionsLoader.java | 6 +- .../gateway/util/TopologyToDescriptor.java | 6 +- .../impl/DefaultKeystoreServiceTest.java | 15 +- .../impl/ZookeeperTokenStateServiceTest.java | 10 +- gateway-service-admin/pom.xml | 31 +- .../service/admin/HrefListingMarshaller.java | 8 +- ...ServiceDefinitionCollectionMarshaller.java | 4 +- .../admin/ServiceDefinitionUnmarshaller.java | 6 +- .../admin/ServiceDefinitionsResource.java | 8 +- .../ServiceDiscoveryCollectionMarshaller.java | 6 +- .../admin/ServiceDiscoveryResource.java | 8 +- .../service/admin/TopologiesResource.java | 8 +- .../admin/TopologyCollectionMarshaller.java | 8 +- .../service/admin/TopologyMarshaller.java | 8 +- .../service/admin/VersionMarshaller.java | 8 +- .../service/admin/VersionResource.java | 4 +- .../service/admin/beans/Application.java | 4 +- .../gateway/service/admin/beans/Param.java | 6 +- .../gateway/service/admin/beans/Provider.java | 6 +- .../gateway/service/admin/beans/Service.java | 6 +- .../gateway/service/admin/beans/Topology.java | 6 +- .../service/admin/TopologyMarshallerTest.java | 6 +- gateway-service-auth/pom.xml | 12 + gateway-service-definitions/pom.xml | 31 +- .../service/definition/CustomDispatch.java | 10 +- .../gateway/service/definition/Metadata.java | 6 +- .../gateway/service/definition/Policy.java | 4 +- .../gateway/service/definition/Rewrite.java | 4 +- .../gateway/service/definition/Route.java | 8 +- .../gateway/service/definition/Sample.java | 4 +- .../service/definition/ServiceDefinition.java | 8 +- .../definition/ServiceDefinitionTest.java | 4 +- gateway-service-hashicorp-vault/pom.xml | 1 + gateway-service-hbase/pom.xml | 4 + gateway-service-hive/pom.xml | 4 + gateway-service-impala/pom.xml | 4 + gateway-service-knoxtoken/pom.xml | 4 + .../service/knoxtoken/TokenResource.java | 6 +- .../knoxtoken/TokenServiceResourceTest.java | 4 + gateway-service-metadata/pom.xml | 6 +- .../metadata/GeneralProxyInformation.java | 4 +- .../GeneralProxyInformationMarshaller.java | 4 +- .../service/metadata/ServiceModel.java | 10 +- .../service/metadata/TopologyInformation.java | 6 +- .../metadata/TopologyInformationWrapper.java | 8 +- .../TopologyInformationWrapperMarshaller.java | 4 +- gateway-service-remoteconfig/pom.xml | 15 +- .../config/RemoteConfigurationRegistries.java | 4 +- .../RemoteConfigurationRegistriesParser.java | 6 +- .../config/RemoteConfigurationRegistry.java | 2 +- gateway-service-session/pom.xml | 6 +- .../service/session/SessionInformation.java | 4 +- .../session/SessionInformationMarshaller.java | 4 +- gateway-service-test/pom.xml | 25 +- .../service/test/ServiceTestResource.java | 10 +- .../test/ServiceTestWrapperMarshaller.java | 8 +- gateway-service-webhdfs/pom.xml | 5 + gateway-shell-release/pom.xml | 21 + gateway-shell/pom.xml | 8 +- .../shell/jdbc/derby/DerbyDatabase.java | 5 +- .../table/JDBCKnoxShellTableBuilder.java | 4 +- gateway-spi/pom.xml | 8 +- .../dispatch/GatewayDispatchFilter.java | 2 +- .../knox/gateway/filter/GatewayRequest.java | 2 +- .../gateway/filter/GatewayRequestWrapper.java | 2 +- .../knox/gateway/filter/GatewayResponse.java | 2 +- .../filter/GatewayResponseWrapper.java | 2 +- .../knox/gateway/security/SubjectUtils.java | 7 + .../definition/ServiceDefinitionPair.java | 10 +- .../UrlRewriteRulesDescriptorAdapter.java | 2 +- .../security/impl/ConfigurableEncryptor.java | 3 +- .../util/GroupBasedImpersonationProvider.java | 264 +++ gateway-test-release-utils/pom.xml | 39 + .../webhdfs-kerb-test/pom.xml | 13 +- gateway-test-release/webhdfs-test/pom.xml | 13 +- .../org/apache/hadoop/http/HttpServer2.java | 1706 ----------------- gateway-test-utils/pom.xml | 5 + .../java/org/apache/knox/test/TestUtils.java | 2 +- .../test/mock/MockHttpServletRequest.java | 2 +- .../knox/test/mock/MockRequestMatcher.java | 2 +- .../knox/test/mock/MockServletContext.java | 2 +- gateway-test/pom.xml | 66 + .../knox/gateway/GatewayAdminFuncTest.java | 3 +- .../gateway/GatewayAdminTopologyFuncTest.java | 5 +- .../gateway/GatewayLocalServiceFuncTest.java | 3 +- .../knox/gateway/GatewaySslFuncTest.java | 3 + gateway-topology-simple/pom.xml | 4 +- .../simple/ProviderConfigurationParser.java | 6 +- .../simple/XMLProviderConfiguration.java | 10 +- gateway-util-common/pom.xml | 15 + .../apache/knox/gateway/util/MimeTypeMap.java | 4 +- .../apache/knox/gateway/util/MimeTypes.java | 4 +- .../gateway/util/X509CertificateUtil.java | 348 +--- .../knox/gateway/util/MimeTypeMapTest.java | 4 +- .../impl/ConfigurationAdapterFactory.java | 10 +- .../impl/DefaultConfigurationInjector.java | 8 +- pom.xml | 188 +- 152 files changed, 1460 insertions(+), 2433 deletions(-) create mode 100644 gateway-provider-jersey/src/main/java/org/apache/knox/gateway/jersey/KnoxFilterUrlMappingsProvider.java create mode 100644 gateway-provider-jersey/src/main/resources/META-INF/services/org.glassfish.jersey.servlet.spi.FilterUrlMappingsProvider create mode 100644 gateway-spi/src/main/java/org/apache/knox/gateway/util/GroupBasedImpersonationProvider.java delete mode 100644 gateway-test-release/webhdfs-test/src/test/java/org/apache/hadoop/http/HttpServer2.java diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 2b185228bf..ba9af3c43f 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -30,7 +30,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - java: [ 8, 11 ] + java: [ 17 ] fail-fast: false name: CI - Java ${{ matrix.java }} steps: diff --git a/build-tools/src/main/resources/build-tools/pmd/pmd-ruleset.xml b/build-tools/src/main/resources/build-tools/pmd/pmd-ruleset.xml index aaad3a12d3..815f49ea90 100644 --- a/build-tools/src/main/resources/build-tools/pmd/pmd-ruleset.xml +++ b/build-tools/src/main/resources/build-tools/pmd/pmd-ruleset.xml @@ -32,32 +32,42 @@ limitations under the License. - - - + - + + + + + + + + + + + + + + + + + - - - - @@ -71,30 +81,40 @@ limitations under the License. - + - - + - - - + + - + + + + + + + + + - - + + + + + + diff --git a/gateway-demo-ldap/pom.xml b/gateway-demo-ldap/pom.xml index efe1269acb..96afc99803 100644 --- a/gateway-demo-ldap/pom.xml +++ b/gateway-demo-ldap/pom.xml @@ -54,6 +54,7 @@ org.apache.directory.api api-ldap-client-api + test org.apache.directory.api @@ -71,6 +72,7 @@ org.apache.mina mina-core + test @@ -89,4 +91,43 @@ bcprov-jdk18on + + + + org.apache.maven.plugins + maven-shade-plugin + + + package + shade + + false + false + + + + *:* + + schema/** + **/*.ldif + + + + + *:* + + META-INF/*.SF + META-INF/*.DSA + META-INF/*.RSA + META-INF/*.EC + META-INF/*.sig + + + + + + + + + diff --git a/gateway-openapi-ui/pom.xml b/gateway-openapi-ui/pom.xml index 287f4fbf4d..538ef62946 100644 --- a/gateway-openapi-ui/pom.xml +++ b/gateway-openapi-ui/pom.xml @@ -86,5 +86,16 @@ org.apache.knox gateway-service-metadata + + + + javax.xml.bind + jaxb-api + ${xml-jaxb.version} + + + org.glassfish.jaxb + jaxb-runtime + diff --git a/gateway-performance-test/pom.xml b/gateway-performance-test/pom.xml index c8f1d8bcec..f54f814fea 100644 --- a/gateway-performance-test/pom.xml +++ b/gateway-performance-test/pom.xml @@ -67,6 +67,10 @@ javax.servlet javax.servlet-api + + com.fasterxml.jackson.core + jackson-core + org.apache.commons commons-lang3 @@ -123,4 +127,4 @@ - \ No newline at end of file + diff --git a/gateway-provider-identity-assertion-common/pom.xml b/gateway-provider-identity-assertion-common/pom.xml index 3c11c73063..9bc29c8549 100644 --- a/gateway-provider-identity-assertion-common/pom.xml +++ b/gateway-provider-identity-assertion-common/pom.xml @@ -40,6 +40,7 @@ org.apache.knox gateway-spi-common + test org.apache.knox @@ -71,9 +72,15 @@ commons-lang3 + + de.thetaphi + forbiddenapis + + org.apache.httpcomponents httpclient + test @@ -88,6 +95,7 @@ org.eclipse.jetty jetty-util + test org.jboss.shrinkwrap.descriptors @@ -96,6 +104,7 @@ org.jboss.shrinkwrap shrinkwrap-api + test diff --git a/gateway-provider-identity-assertion-common/src/main/java/org/apache/knox/gateway/identityasserter/common/filter/AbstractIdentityAssertionFilter.java b/gateway-provider-identity-assertion-common/src/main/java/org/apache/knox/gateway/identityasserter/common/filter/AbstractIdentityAssertionFilter.java index 5202fca08f..8acd260fef 100644 --- a/gateway-provider-identity-assertion-common/src/main/java/org/apache/knox/gateway/identityasserter/common/filter/AbstractIdentityAssertionFilter.java +++ b/gateway-provider-identity-assertion-common/src/main/java/org/apache/knox/gateway/identityasserter/common/filter/AbstractIdentityAssertionFilter.java @@ -52,6 +52,8 @@ import org.apache.knox.gateway.security.PrimaryPrincipal; import org.apache.knox.gateway.security.SubjectUtils; +import de.thetaphi.forbiddenapis.SuppressForbidden; + public abstract class AbstractIdentityAssertionFilter extends AbstractIdentityAssertionBase implements Filter { @@ -87,6 +89,7 @@ public AbstractIdentityAssertionFilter() { */ public abstract String mapUserPrincipal(String principalName); + @SuppressForbidden protected void continueChainAsPrincipal(HttpServletRequestWrapper request, ServletResponse response, FilterChain chain, String mappedPrincipalName, String[] groups) throws IOException, ServletException { diff --git a/gateway-provider-identity-assertion-common/src/main/java/org/apache/knox/gateway/identityasserter/common/filter/CommonIdentityAssertionFilter.java b/gateway-provider-identity-assertion-common/src/main/java/org/apache/knox/gateway/identityasserter/common/filter/CommonIdentityAssertionFilter.java index f82b8b7f19..4792640e47 100644 --- a/gateway-provider-identity-assertion-common/src/main/java/org/apache/knox/gateway/identityasserter/common/filter/CommonIdentityAssertionFilter.java +++ b/gateway-provider-identity-assertion-common/src/main/java/org/apache/knox/gateway/identityasserter/common/filter/CommonIdentityAssertionFilter.java @@ -45,6 +45,7 @@ import javax.servlet.http.HttpServletRequestWrapper; import javax.servlet.http.HttpServletResponse; +import de.thetaphi.forbiddenapis.SuppressForbidden; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.StringUtils; import org.apache.knox.gateway.IdentityAsserterMessages; @@ -221,6 +222,7 @@ public void destroy() { * to the identity to be asserted as appropriate and create the provider specific * assertion token. Add the assertion token to the request. */ + @SuppressForbidden @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { diff --git a/gateway-provider-identity-assertion-hadoop-groups/pom.xml b/gateway-provider-identity-assertion-hadoop-groups/pom.xml index c0aca2c23b..31766b1cff 100644 --- a/gateway-provider-identity-assertion-hadoop-groups/pom.xml +++ b/gateway-provider-identity-assertion-hadoop-groups/pom.xml @@ -37,10 +37,6 @@ org.apache.knox gateway-spi - - org.apache.knox - gateway-spi-common - org.apache.knox gateway-provider-identity-assertion-common @@ -77,6 +73,11 @@ jetty-servlet test + + org.apache.knox + gateway-spi-common + test + org.xmlmatchers diff --git a/gateway-provider-jersey/pom.xml b/gateway-provider-jersey/pom.xml index 862eb63bea..3579a980b4 100644 --- a/gateway-provider-jersey/pom.xml +++ b/gateway-provider-jersey/pom.xml @@ -42,15 +42,24 @@ org.glassfish.jersey.core jersey-server + + org.glassfish.jersey.inject + jersey-hk2 + org.jboss.shrinkwrap shrinkwrap-api + test org.jboss.shrinkwrap.descriptors shrinkwrap-descriptors-api-javaee + + javax.servlet + javax.servlet-api + org.apache.knox diff --git a/gateway-provider-jersey/src/main/java/org/apache/knox/gateway/jersey/KnoxFilterUrlMappingsProvider.java b/gateway-provider-jersey/src/main/java/org/apache/knox/gateway/jersey/KnoxFilterUrlMappingsProvider.java new file mode 100644 index 0000000000..21ab841289 --- /dev/null +++ b/gateway-provider-jersey/src/main/java/org/apache/knox/gateway/jersey/KnoxFilterUrlMappingsProvider.java @@ -0,0 +1,38 @@ +/* + * 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.knox.gateway.jersey; + +import org.glassfish.jersey.servlet.spi.FilterUrlMappingsProvider; +import javax.servlet.FilterConfig; +import java.util.Collections; +import java.util.List; + +/** + * Custom FilterUrlMappingsProvider for Knox that handles null FilterRegistration objects + * gracefully. Jersey 2.47+ expects FilterRegistration objects to be available in the + * ServletContext, but Knox's dynamic filter loading doesn't always provide them. + * This provider returns empty collections to prevent NullPointerExceptions. + */ +public class KnoxFilterUrlMappingsProvider implements FilterUrlMappingsProvider { + @Override + public List getFilterUrlMappings(FilterConfig filterConfig) { + // Return empty list instead of trying to access potentially null FilterRegistration + // This prevents the NullPointerException that occurs in Jersey's FilterUrlMappingsProviderImpl + return Collections.emptyList(); + } +} diff --git a/gateway-provider-jersey/src/main/resources/META-INF/services/org.glassfish.jersey.servlet.spi.FilterUrlMappingsProvider b/gateway-provider-jersey/src/main/resources/META-INF/services/org.glassfish.jersey.servlet.spi.FilterUrlMappingsProvider new file mode 100644 index 0000000000..80fa9a4c1b --- /dev/null +++ b/gateway-provider-jersey/src/main/resources/META-INF/services/org.glassfish.jersey.servlet.spi.FilterUrlMappingsProvider @@ -0,0 +1,19 @@ +########################################################################## +# 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. +########################################################################## + +org.apache.knox.gateway.jersey.KnoxFilterUrlMappingsProvider diff --git a/gateway-provider-rewrite-common/pom.xml b/gateway-provider-rewrite-common/pom.xml index 27baff95fa..965aa4ee1d 100644 --- a/gateway-provider-rewrite-common/pom.xml +++ b/gateway-provider-rewrite-common/pom.xml @@ -42,6 +42,10 @@ gateway-util-urltemplate + + com.sun.activation + jakarta.activation + jakarta.activation jakarta.activation-api diff --git a/gateway-provider-rewrite-common/src/main/java/org/apache/knox/gateway/filter/rewrite/api/UrlRewriteFilterDescriptor.java b/gateway-provider-rewrite-common/src/main/java/org/apache/knox/gateway/filter/rewrite/api/UrlRewriteFilterDescriptor.java index 423b2d1ea2..884979549c 100644 --- a/gateway-provider-rewrite-common/src/main/java/org/apache/knox/gateway/filter/rewrite/api/UrlRewriteFilterDescriptor.java +++ b/gateway-provider-rewrite-common/src/main/java/org/apache/knox/gateway/filter/rewrite/api/UrlRewriteFilterDescriptor.java @@ -17,7 +17,7 @@ */ package org.apache.knox.gateway.filter.rewrite.api; -import javax.activation.MimeType; +import jakarta.activation.MimeType; import java.util.List; public interface UrlRewriteFilterDescriptor { diff --git a/gateway-provider-rewrite-common/src/main/java/org/apache/knox/gateway/filter/rewrite/api/UrlRewriteFunctionDescriptorFactory.java b/gateway-provider-rewrite-common/src/main/java/org/apache/knox/gateway/filter/rewrite/api/UrlRewriteFunctionDescriptorFactory.java index 507b7a76fa..2cc3dcbf11 100644 --- a/gateway-provider-rewrite-common/src/main/java/org/apache/knox/gateway/filter/rewrite/api/UrlRewriteFunctionDescriptorFactory.java +++ b/gateway-provider-rewrite-common/src/main/java/org/apache/knox/gateway/filter/rewrite/api/UrlRewriteFunctionDescriptorFactory.java @@ -17,6 +17,7 @@ */ package org.apache.knox.gateway.filter.rewrite.api; +import java.lang.reflect.InvocationTargetException; import java.util.HashMap; import java.util.Map; import java.util.ServiceLoader; @@ -34,8 +35,8 @@ private UrlRewriteFunctionDescriptorFactory() { public static > T create( String name ) { try { Class descriptorClass = MAP.get( name ); - return (T)descriptorClass.newInstance(); - } catch( InstantiationException | IllegalAccessException e ) { + return (T)descriptorClass.getDeclaredConstructor().newInstance(); + } catch(InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e ) { throw new IllegalArgumentException( name ); } } diff --git a/gateway-provider-rewrite-common/src/main/java/org/apache/knox/gateway/filter/rewrite/api/UrlRewriteStepDescriptorFactory.java b/gateway-provider-rewrite-common/src/main/java/org/apache/knox/gateway/filter/rewrite/api/UrlRewriteStepDescriptorFactory.java index 1b3d309a4e..d5b98af14c 100644 --- a/gateway-provider-rewrite-common/src/main/java/org/apache/knox/gateway/filter/rewrite/api/UrlRewriteStepDescriptorFactory.java +++ b/gateway-provider-rewrite-common/src/main/java/org/apache/knox/gateway/filter/rewrite/api/UrlRewriteStepDescriptorFactory.java @@ -17,6 +17,7 @@ */ package org.apache.knox.gateway.filter.rewrite.api; +import java.lang.reflect.InvocationTargetException; import java.util.HashMap; import java.util.Map; import java.util.ServiceLoader; @@ -33,8 +34,8 @@ private UrlRewriteStepDescriptorFactory() { public static > T create( String type ) { try { Class descriptorClass = MAP.get( type ); - return (T)descriptorClass.newInstance(); - } catch( InstantiationException | IllegalAccessException e ) { + return (T)descriptorClass.getDeclaredConstructor().newInstance(); + } catch(InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e ) { throw new IllegalArgumentException( type ); } } diff --git a/gateway-provider-rewrite-common/src/main/java/org/apache/knox/gateway/filter/rewrite/impl/UrlRewriteFilterDescriptorImpl.java b/gateway-provider-rewrite-common/src/main/java/org/apache/knox/gateway/filter/rewrite/impl/UrlRewriteFilterDescriptorImpl.java index e4aba56660..ce328d85f8 100644 --- a/gateway-provider-rewrite-common/src/main/java/org/apache/knox/gateway/filter/rewrite/impl/UrlRewriteFilterDescriptorImpl.java +++ b/gateway-provider-rewrite-common/src/main/java/org/apache/knox/gateway/filter/rewrite/impl/UrlRewriteFilterDescriptorImpl.java @@ -21,8 +21,8 @@ import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteFilterDescriptor; import org.apache.knox.gateway.util.MimeTypeMap; -import javax.activation.MimeType; -import javax.activation.MimeTypeParseException; +import jakarta.activation.MimeType; +import jakarta.activation.MimeTypeParseException; import java.util.ArrayList; import java.util.List; diff --git a/gateway-provider-rewrite-func-hostmap-static/pom.xml b/gateway-provider-rewrite-func-hostmap-static/pom.xml index a8e11dcd4d..2c7b3c22e4 100644 --- a/gateway-provider-rewrite-func-hostmap-static/pom.xml +++ b/gateway-provider-rewrite-func-hostmap-static/pom.xml @@ -54,6 +54,7 @@ commons-io commons-io + test diff --git a/gateway-provider-rewrite-func-inbound-query-param/pom.xml b/gateway-provider-rewrite-func-inbound-query-param/pom.xml index d0948db550..1afdd9299b 100644 --- a/gateway-provider-rewrite-func-inbound-query-param/pom.xml +++ b/gateway-provider-rewrite-func-inbound-query-param/pom.xml @@ -34,6 +34,7 @@ org.apache.knox gateway-spi + test org.apache.knox @@ -51,6 +52,7 @@ javax.servlet javax.servlet-api + test diff --git a/gateway-provider-rewrite-func-service-registry/pom.xml b/gateway-provider-rewrite-func-service-registry/pom.xml index a8529ac033..f92d1dda58 100644 --- a/gateway-provider-rewrite-func-service-registry/pom.xml +++ b/gateway-provider-rewrite-func-service-registry/pom.xml @@ -60,23 +60,24 @@ - org.apache.httpcomponents - httpclient + org.eclipse.jetty + jetty-http + + + + - org.eclipse.jetty - jetty-http + org.apache.httpcomponents + httpclient + test org.eclipse.jetty jetty-util + test - - - - - org.apache.knox gateway-test-utils @@ -108,6 +109,7 @@ javax.servlet javax.servlet-api + test diff --git a/gateway-provider-rewrite-step-encrypt-uri/pom.xml b/gateway-provider-rewrite-step-encrypt-uri/pom.xml index f4d6715925..9ce699984a 100644 --- a/gateway-provider-rewrite-step-encrypt-uri/pom.xml +++ b/gateway-provider-rewrite-step-encrypt-uri/pom.xml @@ -78,6 +78,16 @@ gateway-test-utils test + + org.jboss.shrinkwrap + shrinkwrap-api + test + + + commons-cli + commons-cli + test + org.apache.velocity velocity-engine-core diff --git a/gateway-provider-rewrite-step-secure-query/pom.xml b/gateway-provider-rewrite-step-secure-query/pom.xml index 3b1ef02345..a257c62557 100644 --- a/gateway-provider-rewrite-step-secure-query/pom.xml +++ b/gateway-provider-rewrite-step-secure-query/pom.xml @@ -64,11 +64,6 @@ commons-codec - - org.jboss.shrinkwrap - shrinkwrap-api - - @@ -79,6 +74,18 @@ test + + org.jboss.shrinkwrap + shrinkwrap-api + test + + + + commons-cli + commons-cli + test + + org.apache.knox gateway-server diff --git a/gateway-provider-rewrite/pom.xml b/gateway-provider-rewrite/pom.xml index e89e2085b1..9418f77d19 100644 --- a/gateway-provider-rewrite/pom.xml +++ b/gateway-provider-rewrite/pom.xml @@ -62,10 +62,6 @@ org.apache.commons commons-compress - - org.apache.commons - commons-digester3 - commons-io commons-io @@ -90,14 +86,7 @@ com.fasterxml.jackson.core jackson-databind - - org.apache.httpcomponents - httpcore - - - org.apache.httpcomponents - httpclient - + org.jboss.shrinkwrap shrinkwrap-api @@ -110,28 +99,59 @@ org.eclipse.jetty jetty-http - - org.eclipse.jetty - jetty-util - javax.servlet javax.servlet-api + + com.sun.activation + jakarta.activation + jakarta.activation jakarta.activation-api + + + + + + org.apache.commons + commons-digester3 + test + + + org.eclipse.jetty + jetty-util + test + org.apache.logging.log4j log4j-api + test org.apache.logging.log4j log4j-core + test + + + org.apache.httpcomponents + httpcore + test + + + org.apache.httpcomponents + httpclient + test + + + + de.thetaphi + forbiddenapis diff --git a/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/api/UrlRewriteServletFilter.java b/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/api/UrlRewriteServletFilter.java index eea17a5666..dfc3a10bce 100644 --- a/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/api/UrlRewriteServletFilter.java +++ b/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/api/UrlRewriteServletFilter.java @@ -22,7 +22,7 @@ import org.apache.knox.gateway.filter.rewrite.impl.UrlRewriteResponse; import org.apache.knox.gateway.util.MimeTypes; -import javax.activation.MimeType; +import jakarta.activation.MimeType; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; diff --git a/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/api/UrlRewriteStreamFilterFactory.java b/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/api/UrlRewriteStreamFilterFactory.java index 5a5681ea63..f81a4e82a6 100644 --- a/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/api/UrlRewriteStreamFilterFactory.java +++ b/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/api/UrlRewriteStreamFilterFactory.java @@ -21,8 +21,8 @@ import org.apache.knox.gateway.util.MimeTypes; import org.apache.knox.gateway.util.urltemplate.Resolver; -import javax.activation.MimeType; -import javax.activation.MimeTypeParseException; +import jakarta.activation.MimeType; +import jakarta.activation.MimeTypeParseException; import java.io.IOException; import java.io.InputStream; import java.nio.charset.StandardCharsets; diff --git a/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/impl/UrlRewriteFunctionProcessorFactory.java b/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/impl/UrlRewriteFunctionProcessorFactory.java index 0035c68b2c..1e5dddabee 100644 --- a/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/impl/UrlRewriteFunctionProcessorFactory.java +++ b/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/impl/UrlRewriteFunctionProcessorFactory.java @@ -21,6 +21,7 @@ import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteFunctionDescriptorFactory; import org.apache.knox.gateway.filter.rewrite.spi.UrlRewriteFunctionProcessor; +import java.lang.reflect.InvocationTargetException; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.HashMap; @@ -36,7 +37,7 @@ private UrlRewriteFunctionProcessorFactory() { } public static UrlRewriteFunctionProcessor create( String name, UrlRewriteFunctionDescriptor descriptor ) - throws IllegalAccessException, InstantiationException { + throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException { UrlRewriteFunctionProcessor processor; if( descriptor == null ) { descriptor = UrlRewriteFunctionDescriptorFactory.create( name ); @@ -54,7 +55,7 @@ public static UrlRewriteFunctionProcessor create( String name, UrlRewriteFunctio if( processorClass == null ) { throw new IllegalArgumentException( name ); } else { - processor = processorClass.newInstance(); + processor = processorClass.getDeclaredConstructor().newInstance(); } } return processor; diff --git a/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/impl/UrlRewriteRequest.java b/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/impl/UrlRewriteRequest.java index 48602330ef..e02b5de1f5 100644 --- a/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/impl/UrlRewriteRequest.java +++ b/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/impl/UrlRewriteRequest.java @@ -36,7 +36,7 @@ import org.apache.knox.gateway.util.urltemplate.Template; import org.eclipse.jetty.http.HttpHeader; -import javax.activation.MimeType; +import jakarta.activation.MimeType; import javax.servlet.FilterConfig; import javax.servlet.ServletInputStream; import javax.servlet.http.HttpServletRequest; diff --git a/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/impl/UrlRewriteResponse.java b/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/impl/UrlRewriteResponse.java index 73f16ba2ca..07b518a595 100644 --- a/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/impl/UrlRewriteResponse.java +++ b/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/impl/UrlRewriteResponse.java @@ -36,7 +36,7 @@ import org.apache.knox.gateway.util.urltemplate.Template; import org.apache.commons.io.IOUtils; -import javax.activation.MimeType; +import jakarta.activation.MimeType; import javax.servlet.FilterConfig; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletRequest; diff --git a/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/impl/UrlRewriteStepProcessorFactory.java b/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/impl/UrlRewriteStepProcessorFactory.java index 3851396385..4baf2d5c08 100644 --- a/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/impl/UrlRewriteStepProcessorFactory.java +++ b/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/impl/UrlRewriteStepProcessorFactory.java @@ -20,6 +20,7 @@ import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteStepDescriptor; import org.apache.knox.gateway.filter.rewrite.spi.UrlRewriteStepProcessor; +import java.lang.reflect.InvocationTargetException; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.HashMap; @@ -34,7 +35,7 @@ public abstract class UrlRewriteStepProcessorFactory { private UrlRewriteStepProcessorFactory() { } - public static UrlRewriteStepProcessor create( UrlRewriteStepDescriptor descriptor ) throws IllegalAccessException, InstantiationException { + public static UrlRewriteStepProcessor create( UrlRewriteStepDescriptor descriptor ) throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException { UrlRewriteStepProcessor processor; Map> typeMap; typeMap = MAP.get( descriptor.getClass() ); @@ -50,7 +51,7 @@ public static UrlRewriteStepProcessor create( UrlRewriteStepDescriptor descripto if( processorClass == null ) { throw new IllegalArgumentException( type ); } else { - processor = processorClass.newInstance(); + processor = processorClass.getDeclaredConstructor().newInstance(); } } return processor; diff --git a/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/impl/UrlRewriteUtil.java b/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/impl/UrlRewriteUtil.java index b7b665c0c5..32ab9e3f3e 100644 --- a/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/impl/UrlRewriteUtil.java +++ b/gateway-provider-rewrite/src/main/java/org/apache/knox/gateway/filter/rewrite/impl/UrlRewriteUtil.java @@ -26,7 +26,7 @@ import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteFilterPathDescriptor; import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteRulesDescriptor; -import javax.activation.MimeType; +import jakarta.activation.MimeType; public class UrlRewriteUtil { diff --git a/gateway-provider-security-authc-remote/src/test/java/org/apache/knox/gateway/filter/RemoteAuthFilterTest.java b/gateway-provider-security-authc-remote/src/test/java/org/apache/knox/gateway/filter/RemoteAuthFilterTest.java index 0c269a3807..a1c5ae02a0 100644 --- a/gateway-provider-security-authc-remote/src/test/java/org/apache/knox/gateway/filter/RemoteAuthFilterTest.java +++ b/gateway-provider-security-authc-remote/src/test/java/org/apache/knox/gateway/filter/RemoteAuthFilterTest.java @@ -19,6 +19,7 @@ import org.apache.knox.gateway.security.GroupPrincipal; import org.apache.knox.gateway.security.PrimaryPrincipal; +import org.apache.knox.gateway.security.SubjectUtils; import org.apache.knox.gateway.services.GatewayServices; import org.apache.knox.gateway.services.ServiceType; import org.apache.knox.gateway.services.security.AliasService; @@ -42,7 +43,6 @@ import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; -import java.security.AccessController; import java.security.Principal; import java.util.ArrayList; import java.util.Arrays; @@ -514,7 +514,7 @@ protected static class TestFilterChain implements FilterChain { public void doFilter(ServletRequest request, ServletResponse response) { doFilterCalled = true; - subject = Subject.getSubject( AccessController.getContext() ); + subject = SubjectUtils.getCurrentSubject(); } public Subject getSubject() { diff --git a/gateway-provider-security-clientcert/src/main/java/org/apache/knox/gateway/clientcert/filter/ClientCertFilter.java b/gateway-provider-security-clientcert/src/main/java/org/apache/knox/gateway/clientcert/filter/ClientCertFilter.java index 95de828dac..3b4f8528d9 100755 --- a/gateway-provider-security-clientcert/src/main/java/org/apache/knox/gateway/clientcert/filter/ClientCertFilter.java +++ b/gateway-provider-security-clientcert/src/main/java/org/apache/knox/gateway/clientcert/filter/ClientCertFilter.java @@ -88,7 +88,7 @@ public void doFilter(ServletRequest request, ServletResponse response, FilterCha private String extractPrincipalFromCert(X509Certificate cert) { String p = null; if ("DN".equalsIgnoreCase(principalAttributeName)) { - p = cert.getSubjectDN().getName(); + p = cert.getSubjectX500Principal().getName(); } else if ("CN".equalsIgnoreCase(principalAttributeName)) { X500Principal x500Principal = cert.getSubjectX500Principal(); @@ -97,7 +97,7 @@ else if ("CN".equalsIgnoreCase(principalAttributeName)) { } else { log.unknownCertificateAttribute(principalAttributeName); - p = cert.getSubjectDN().getName(); + p = cert.getSubjectX500Principal().getName(); } return p; diff --git a/gateway-provider-security-hadoopauth/pom.xml b/gateway-provider-security-hadoopauth/pom.xml index af76bfa543..59bfe47666 100755 --- a/gateway-provider-security-hadoopauth/pom.xml +++ b/gateway-provider-security-hadoopauth/pom.xml @@ -45,10 +45,7 @@ org.apache.knox gateway-spi - - org.apache.knox - gateway-spi-common - + org.apache.knox gateway-util-common @@ -69,16 +66,30 @@ javax.servlet-api - - org.jboss.shrinkwrap - shrinkwrap-api - + org.apache.commons commons-lang3 + + org.apache.hadoop + hadoop-common + + + + de.thetaphi + forbiddenapis + test + + + + org.apache.knox + gateway-spi-common + test + + org.apache.knox gateway-test-utils @@ -86,10 +97,13 @@ - org.apache.hadoop - hadoop-common + org.jboss.shrinkwrap + shrinkwrap-api + test + + org.apache.knox gateway-provider-security-pac4j diff --git a/gateway-provider-security-hadoopauth/src/test/java/org/apache/knox/gateway/hadoopauth/filter/HadoopAuthFilterTest.java b/gateway-provider-security-hadoopauth/src/test/java/org/apache/knox/gateway/hadoopauth/filter/HadoopAuthFilterTest.java index 934959f277..adc554bb94 100644 --- a/gateway-provider-security-hadoopauth/src/test/java/org/apache/knox/gateway/hadoopauth/filter/HadoopAuthFilterTest.java +++ b/gateway-provider-security-hadoopauth/src/test/java/org/apache/knox/gateway/hadoopauth/filter/HadoopAuthFilterTest.java @@ -33,6 +33,7 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import de.thetaphi.forbiddenapis.SuppressForbidden; import org.apache.knox.gateway.GatewayFilter; import org.apache.knox.gateway.config.GatewayConfig; import org.apache.knox.gateway.context.ContextAttributes; @@ -547,6 +548,7 @@ public static class DummyFilterChain implements FilterChain { boolean doFilterCalled; Subject subject; + @SuppressForbidden @Override public void doFilter(ServletRequest request, ServletResponse response) throws IOException { diff --git a/gateway-provider-security-jwt/pom.xml b/gateway-provider-security-jwt/pom.xml index 945b7e793e..4b729d39b2 100644 --- a/gateway-provider-security-jwt/pom.xml +++ b/gateway-provider-security-jwt/pom.xml @@ -51,6 +51,13 @@ commons-io + + de.thetaphi + forbiddenapis + 3.9 + compile + + org.eclipse.jetty jetty-http @@ -71,6 +78,11 @@ commons-lang3 + + org.jline + jline + + org.apache.knox gateway-test-utils diff --git a/gateway-provider-security-jwt/src/main/java/org/apache/knox/gateway/provider/federation/jwt/filter/JWTAccessTokenAssertionFilter.java b/gateway-provider-security-jwt/src/main/java/org/apache/knox/gateway/provider/federation/jwt/filter/JWTAccessTokenAssertionFilter.java index fbcef111eb..4d6b56a547 100644 --- a/gateway-provider-security-jwt/src/main/java/org/apache/knox/gateway/provider/federation/jwt/filter/JWTAccessTokenAssertionFilter.java +++ b/gateway-provider-security-jwt/src/main/java/org/apache/knox/gateway/provider/federation/jwt/filter/JWTAccessTokenAssertionFilter.java @@ -31,6 +31,7 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import de.thetaphi.forbiddenapis.SuppressForbidden; import org.apache.commons.lang3.StringUtils; import org.apache.knox.gateway.filter.security.AbstractIdentityAssertionFilter; import org.apache.knox.gateway.i18n.messages.MessagesFactory; @@ -77,6 +78,7 @@ public void init( FilterConfig filterConfig ) throws ServletException { : filterConfig.getInitParameter(JWTAccessTokenAssertionFilter.ISSUER); } + @SuppressForbidden @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { diff --git a/gateway-provider-security-jwt/src/main/java/org/apache/knox/gateway/provider/federation/jwt/filter/JWTAuthCodeAssertionFilter.java b/gateway-provider-security-jwt/src/main/java/org/apache/knox/gateway/provider/federation/jwt/filter/JWTAuthCodeAssertionFilter.java index 4589bfcae2..8aed952518 100644 --- a/gateway-provider-security-jwt/src/main/java/org/apache/knox/gateway/provider/federation/jwt/filter/JWTAuthCodeAssertionFilter.java +++ b/gateway-provider-security-jwt/src/main/java/org/apache/knox/gateway/provider/federation/jwt/filter/JWTAuthCodeAssertionFilter.java @@ -28,6 +28,7 @@ import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; +import de.thetaphi.forbiddenapis.SuppressForbidden; import org.apache.commons.lang3.StringUtils; import org.apache.knox.gateway.filter.security.AbstractIdentityAssertionFilter; import org.apache.knox.gateway.services.ServiceType; @@ -64,6 +65,7 @@ public void init( FilterConfig filterConfig ) throws ServletException { : filterConfig.getInitParameter(JWTAccessTokenAssertionFilter.ISSUER); } + @SuppressForbidden @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException { diff --git a/gateway-provider-security-jwt/src/test/java/org/apache/knox/gateway/provider/federation/AbstractJWTFilterTest.java b/gateway-provider-security-jwt/src/test/java/org/apache/knox/gateway/provider/federation/AbstractJWTFilterTest.java index 7ca72cd400..dfa55a7d68 100644 --- a/gateway-provider-security-jwt/src/test/java/org/apache/knox/gateway/provider/federation/AbstractJWTFilterTest.java +++ b/gateway-provider-security-jwt/src/test/java/org/apache/knox/gateway/provider/federation/AbstractJWTFilterTest.java @@ -26,6 +26,7 @@ import com.nimbusds.jose.crypto.RSASSAVerifier; import com.nimbusds.jwt.JWTClaimsSet; import com.nimbusds.jwt.SignedJWT; +import de.thetaphi.forbiddenapis.SuppressForbidden; import org.apache.commons.codec.binary.Base64; import org.apache.knox.gateway.config.GatewayConfig; import org.apache.knox.gateway.provider.federation.jwt.filter.AbstractJWTFilter; @@ -1476,6 +1477,7 @@ protected static class TestFilterChain implements FilterChain { boolean doFilterCalled; Subject subject; + @SuppressForbidden @Override public void doFilter(ServletRequest request, ServletResponse response) { doFilterCalled = true; diff --git a/gateway-provider-security-jwt/src/test/java/org/apache/knox/gateway/provider/federation/CommonJWTFilterTest.java b/gateway-provider-security-jwt/src/test/java/org/apache/knox/gateway/provider/federation/CommonJWTFilterTest.java index b01fd35cc7..d29b8e380d 100644 --- a/gateway-provider-security-jwt/src/test/java/org/apache/knox/gateway/provider/federation/CommonJWTFilterTest.java +++ b/gateway-provider-security-jwt/src/test/java/org/apache/knox/gateway/provider/federation/CommonJWTFilterTest.java @@ -16,6 +16,7 @@ */ package org.apache.knox.gateway.provider.federation; +import de.thetaphi.forbiddenapis.SuppressForbidden; import org.apache.knox.gateway.config.GatewayConfig; import org.apache.knox.gateway.provider.federation.jwt.filter.AbstractJWTFilter; import org.apache.knox.gateway.provider.federation.jwt.filter.JWTFederationFilter; @@ -175,6 +176,7 @@ public static class DummyFilterChain implements FilterChain { boolean doFilterCalled; Subject subject; + @SuppressForbidden @Override public void doFilter(ServletRequest request, ServletResponse response) throws IOException { diff --git a/gateway-provider-security-pac4j/pom.xml b/gateway-provider-security-pac4j/pom.xml index 5c2173627b..5e27fa3aba 100644 --- a/gateway-provider-security-pac4j/pom.xml +++ b/gateway-provider-security-pac4j/pom.xml @@ -36,6 +36,7 @@ org.apache.knox gateway-server + test org.apache.knox @@ -163,5 +164,10 @@ org.bouncycastle bcpkix-jdk18on + + commons-cli + commons-cli + test + diff --git a/gateway-provider-security-shiro/pom.xml b/gateway-provider-security-shiro/pom.xml index 172b27e3cb..8cce8d339b 100644 --- a/gateway-provider-security-shiro/pom.xml +++ b/gateway-provider-security-shiro/pom.xml @@ -54,10 +54,6 @@ org.jboss.shrinkwrap shrinkwrap-api - - org.jboss.shrinkwrap.descriptors - shrinkwrap-descriptors-api-base - org.jboss.shrinkwrap.descriptors shrinkwrap-descriptors-api-javaee @@ -97,6 +93,34 @@ javax.servlet-api + + + javax.xml.bind + jaxb-api + ${xml-jaxb.version} + + + org.glassfish.jaxb + jaxb-runtime + + + jakarta.activation + jakarta.activation-api + + + org.jboss.shrinkwrap.descriptors + shrinkwrap-descriptors-api-base + + + com.sun.activation + jakarta.activation + + + commons-cli + commons-cli + test + + org.apache.knox gateway-test-utils diff --git a/gateway-provider-security-webappsec/pom.xml b/gateway-provider-security-webappsec/pom.xml index 50f8ef78c5..c4c184f9ad 100644 --- a/gateway-provider-security-webappsec/pom.xml +++ b/gateway-provider-security-webappsec/pom.xml @@ -40,6 +40,7 @@ org.apache.knox gateway-spi-common + test org.apache.knox diff --git a/gateway-release-common/home/bin/knox-functions.sh b/gateway-release-common/home/bin/knox-functions.sh index 7cea1c5e8d..7bd072abe3 100644 --- a/gateway-release-common/home/bin/knox-functions.sh +++ b/gateway-release-common/home/bin/knox-functions.sh @@ -165,7 +165,7 @@ function addJdk17Properties { CHECK_VERSION_17="17" if [[ "$JAVA_VERSION" == *"$CHECK_VERSION_17"* ]]; then echo "Java version is $CHECK_VERSION_17. Adding properties to enable Knox to run on JDK 17" - addAppJavaOpts " --add-exports java.base/sun.security.x509=ALL-UNNAMED --add-exports java.base/sun.security.pkcs=ALL-UNNAMED --add-exports java.naming/com.sun.jndi.ldap=ALL-UNNAMED --add-opens java.base/sun.security.util=ALL-UNNAMED --add-exports java.base/jdk.internal.misc=ALL-UNNAMED --add-opens=java.base/java.lang=ALL-UNNAMED --add-exports java.base/sun.net.util=ALL-UNNAMED --add-exports java.base/sun.net.dns=ALL-UNNAMED" + addAppJavaOpts "-Dcom.sun.xml.bind.v2.bytecode.ClassTailor.noOptimize=true --add-exports java.base/sun.security.x509=ALL-UNNAMED --add-exports java.base/sun.security.pkcs=ALL-UNNAMED --add-exports java.naming/com.sun.jndi.ldap=ALL-UNNAMED --add-opens java.base/sun.security.util=ALL-UNNAMED" fi } diff --git a/gateway-release/pom.xml b/gateway-release/pom.xml index b38fa22036..8ae1ee066a 100644 --- a/gateway-release/pom.xml +++ b/gateway-release/pom.xml @@ -202,6 +202,41 @@ + + org.apache.maven.plugins + maven-shade-plugin + + + package + shade + + true + false + + + + *:* + + schema/** + **/*.ldif + + + + + *:* + + META-INF/*.SF + META-INF/*.DSA + META-INF/*.RSA + META-INF/*.EC + META-INF/*.sig + + + + + + + diff --git a/gateway-server/pom.xml b/gateway-server/pom.xml index c826888f1d..9b254163eb 100644 --- a/gateway-server/pom.xml +++ b/gateway-server/pom.xml @@ -29,6 +29,10 @@ gateway-server The gateway server implementation. + + --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.io=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.util.concurrent=ALL-UNNAMED --add-opens java.base/java.lang.reflect=ALL-UNNAMED --add-opens java.base/sun.reflect=ALL-UNNAMED --add-opens java.base/java.text=ALL-UNNAMED --add-opens java.desktop/java.awt.font=ALL-UNNAMED --add-opens java.base/java.lang.invoke=ALL-UNNAMED --add-opens java.base/java.security=ALL-UNNAMED --add-opens java.base/java.util.concurrent.atomic=ALL-UNNAMED --add-opens java.base/sun.security.util=ALL-UNNAMED + + @@ -46,13 +50,18 @@ + + + org.apache.maven.plugins + maven-surefire-plugin + + @{argLine} ${maven.surefire.argLine} + + + - - org.eclipse.persistence - eclipselink - javax.json javax.json-api @@ -61,6 +70,14 @@ org.glassfish javax.json + + jakarta.json + jakarta.json-api + + + org.eclipse.parsson + parsson + org.apache.knox gateway-provider-rewrite-common @@ -130,6 +147,7 @@ org.apache.logging.log4j log4j-core + test @@ -162,16 +180,16 @@ javax.servlet-api - - com.sun.xml.ws - jaxws-ri - pom - - jakarta.xml.bind jakarta.xml.bind-api + org.apache.httpcomponents @@ -309,6 +327,15 @@ apache-jstl + + org.eclipse.persistence + org.eclipse.persistence.core + + + org.eclipse.persistence + org.eclipse.persistence.moxy + + org.eclipse.jetty.websocket @@ -369,44 +396,24 @@ org.apache.curator curator-client + test org.apache.curator curator-framework + test org.apache.zookeeper zookeeper - - org.apache.zookeeper - zookeeper-jute - com.nimbusds nimbus-jose-jwt - - javax.xml.bind - jaxb-api - - - com.sun.xml.bind - jaxb-core - - - com.sun.xml.bind - jaxb-impl - - - - org.glassfish.jaxb - jaxb-runtime - - org.apache.knox gateway-util-configinjector @@ -507,6 +514,11 @@ jersey-server test + + org.glassfish.jersey.inject + jersey-hk2 + test + com.mycila.xmltool @@ -535,5 +547,10 @@ powermock-core test + + org.apache.zookeeper + zookeeper-jute + test + diff --git a/gateway-server/src/main/java/org/apache/knox/gateway/GatewayFilter.java b/gateway-server/src/main/java/org/apache/knox/gateway/GatewayFilter.java index 1585aa6966..3f7adf8807 100644 --- a/gateway-server/src/main/java/org/apache/knox/gateway/GatewayFilter.java +++ b/gateway-server/src/main/java/org/apache/knox/gateway/GatewayFilter.java @@ -418,7 +418,7 @@ private Filter getInstance() throws ServletException { if( clazz == null ) { clazz = getClazz(); } - Filter f = clazz.newInstance(); + Filter f = clazz.getDeclaredConstructor().newInstance(); f.init(this); instance = f; } catch( Exception e ) { diff --git a/gateway-server/src/main/java/org/apache/knox/gateway/deploy/DeploymentFactory.java b/gateway-server/src/main/java/org/apache/knox/gateway/deploy/DeploymentFactory.java index cc0861f418..dfe4a4ea90 100644 --- a/gateway-server/src/main/java/org/apache/knox/gateway/deploy/DeploymentFactory.java +++ b/gateway-server/src/main/java/org/apache/knox/gateway/deploy/DeploymentFactory.java @@ -34,6 +34,7 @@ import org.apache.knox.gateway.topology.Version; import org.apache.knox.gateway.util.ServiceDefinitionsLoader; import org.apache.knox.gateway.util.Urls; +import org.eclipse.persistence.jaxb.JAXBContextProperties; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.Asset; import org.jboss.shrinkwrap.api.asset.StringAsset; @@ -44,9 +45,9 @@ import org.jboss.shrinkwrap.descriptor.api.webcommon30.FilterType; import org.jboss.shrinkwrap.descriptor.api.webcommon30.ServletType; -import javax.xml.bind.JAXBContext; -import javax.xml.bind.JAXBException; -import javax.xml.bind.Marshaller; +import jakarta.xml.bind.JAXBContext; +import jakarta.xml.bind.JAXBException; +import jakarta.xml.bind.Marshaller; import java.beans.Statement; import java.io.File; import java.io.IOException; @@ -86,11 +87,12 @@ public abstract class DeploymentFactory { private static JAXBContext getJAXBContext() { Map properties = new HashMap<>(2); - properties.put( "eclipselink-oxm-xml", "org/apache/knox/gateway/topology/topology_binding-xml.xml"); - properties.put( "eclipselink.media-type", "application/xml" ); + properties.put( JAXBContextProperties.OXM_METADATA_SOURCE, "org/apache/knox/gateway/topology/topology_binding-xml.xml"); + properties.put( JAXBContextProperties.MEDIA_TYPE, "application/xml" ); try { return JAXBContext.newInstance(Topology.class.getPackage().getName(), Topology.class.getClassLoader(), properties); + //return JAXBContext.newInstance(Topology.class); } catch (JAXBException e) { throw new IllegalStateException(e); } diff --git a/gateway-server/src/main/java/org/apache/knox/gateway/deploy/impl/ApplicationDeploymentContributor.java b/gateway-server/src/main/java/org/apache/knox/gateway/deploy/impl/ApplicationDeploymentContributor.java index eac88d8244..1e4d1f6a5a 100644 --- a/gateway-server/src/main/java/org/apache/knox/gateway/deploy/impl/ApplicationDeploymentContributor.java +++ b/gateway-server/src/main/java/org/apache/knox/gateway/deploy/impl/ApplicationDeploymentContributor.java @@ -37,9 +37,9 @@ import org.apache.knox.gateway.topology.Service; import org.apache.knox.gateway.topology.Version; -import javax.xml.bind.JAXBContext; -import javax.xml.bind.JAXBException; -import javax.xml.bind.Unmarshaller; +import jakarta.xml.bind.JAXBContext; +import jakarta.xml.bind.JAXBException; +import jakarta.xml.bind.Unmarshaller; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; diff --git a/gateway-server/src/main/java/org/apache/knox/gateway/model/Topology.java b/gateway-server/src/main/java/org/apache/knox/gateway/model/Topology.java index 419b652c50..fda6ad951a 100644 --- a/gateway-server/src/main/java/org/apache/knox/gateway/model/Topology.java +++ b/gateway-server/src/main/java/org/apache/knox/gateway/model/Topology.java @@ -28,11 +28,11 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlElementWrapper; -import javax.xml.bind.annotation.XmlRootElement; +import jakarta.xml.bind.annotation.XmlAccessType; +import jakarta.xml.bind.annotation.XmlAccessorType; +import jakarta.xml.bind.annotation.XmlElement; +import jakarta.xml.bind.annotation.XmlElementWrapper; +import jakarta.xml.bind.annotation.XmlRootElement; import java.io.IOException; import java.net.URI; import java.util.ArrayList; diff --git a/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/AbstractServiceFactory.java b/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/AbstractServiceFactory.java index 4ead5d6cf4..4b60fa434e 100644 --- a/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/AbstractServiceFactory.java +++ b/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/AbstractServiceFactory.java @@ -17,6 +17,7 @@ */ package org.apache.knox.gateway.services.factory; +import java.lang.reflect.InvocationTargetException; import java.util.Collection; import java.util.Map; @@ -53,9 +54,10 @@ public Service create(GatewayServices gatewayServices, ServiceType serviceType, if (service == null && StringUtils.isNotBlank(implementation)) { // no known service implementation created, try to create the custom one try { - service = (Service) Class.forName(implementation).newInstance(); + service = (Service) Class.forName(implementation).getDeclaredConstructor().newInstance(); logServiceUsage(implementation, serviceType); - } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) { + } catch (InstantiationException | IllegalAccessException | ClassNotFoundException | NoSuchMethodException | + InvocationTargetException e) { throw new ServiceLifecycleException("Error while instantiating " + serviceType.getShortName() + " service implementation " + implementation, e); } } diff --git a/gateway-server/src/main/java/org/apache/knox/gateway/services/registry/impl/DefaultServiceDefinitionRegistry.java b/gateway-server/src/main/java/org/apache/knox/gateway/services/registry/impl/DefaultServiceDefinitionRegistry.java index 41030c275e..44bfd4b209 100644 --- a/gateway-server/src/main/java/org/apache/knox/gateway/services/registry/impl/DefaultServiceDefinitionRegistry.java +++ b/gateway-server/src/main/java/org/apache/knox/gateway/services/registry/impl/DefaultServiceDefinitionRegistry.java @@ -44,9 +44,9 @@ import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.stream.Collectors; -import javax.xml.bind.JAXBContext; -import javax.xml.bind.JAXBException; -import javax.xml.bind.Marshaller; +import jakarta.xml.bind.JAXBContext; +import jakarta.xml.bind.JAXBException; +import jakarta.xml.bind.Marshaller; import org.apache.knox.gateway.GatewayMessages; import org.apache.knox.gateway.config.GatewayConfig; diff --git a/gateway-server/src/main/java/org/apache/knox/gateway/services/registry/impl/DefaultServiceRegistryService.java b/gateway-server/src/main/java/org/apache/knox/gateway/services/registry/impl/DefaultServiceRegistryService.java index 124c9d95b9..45d8edb6f5 100644 --- a/gateway-server/src/main/java/org/apache/knox/gateway/services/registry/impl/DefaultServiceRegistryService.java +++ b/gateway-server/src/main/java/org/apache/knox/gateway/services/registry/impl/DefaultServiceRegistryService.java @@ -42,6 +42,8 @@ public class DefaultServiceRegistryService implements ServiceRegistry, Service { private static GatewayMessages LOG = MessagesFactory.get( GatewayMessages.class ); + private static final SecureRandom SECURE_RANDOM = new SecureRandom(); + protected char[] chars = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'j', 'k', 'm', 'n', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', @@ -71,9 +73,8 @@ public String getRegistrationCode(String clusterName) { private String generateRegCode(int length) { StringBuilder sb = new StringBuilder(); - SecureRandom r = new SecureRandom(); for (int i = 0; i < length; i++) { - sb.append(chars[r.nextInt(chars.length)]); + sb.append(chars[SECURE_RANDOM.nextInt(chars.length)]); } return sb.toString(); } diff --git a/gateway-server/src/main/java/org/apache/knox/gateway/services/token/impl/ZookeeperTokenStateService.java b/gateway-server/src/main/java/org/apache/knox/gateway/services/token/impl/ZookeeperTokenStateService.java index 70aad418f5..7fdc3000d2 100644 --- a/gateway-server/src/main/java/org/apache/knox/gateway/services/token/impl/ZookeeperTokenStateService.java +++ b/gateway-server/src/main/java/org/apache/knox/gateway/services/token/impl/ZookeeperTokenStateService.java @@ -43,6 +43,10 @@ */ public class ZookeeperTokenStateService extends AliasBasedTokenStateService implements RemoteTokenStateChangeListener { + // Constants for token aliases - needed for test compatibility + public static final String TOKEN_MAX_LIFETIME_POSTFIX = AliasBasedTokenStateService.TOKEN_MAX_LIFETIME_POSTFIX; + public static final String TOKEN_META_POSTFIX = AliasBasedTokenStateService.TOKEN_META_POSTFIX; + private final GatewayServices gatewayServices; private final AliasServiceFactory aliasServiceFactory; @@ -58,14 +62,31 @@ public ZookeeperTokenStateService(GatewayServices gatewayServices, AliasServiceF @Override public void init(GatewayConfig config, Map options) throws ServiceLifecycleException { log.deprecatedServiceUsage(this.getClass().getCanonicalName()); - final ZookeeperRemoteAliasService zookeeperAliasService = (ZookeeperRemoteAliasService) aliasServiceFactory.create(gatewayServices, ALIAS_SERVICE, config, options, + + final Object createdService = aliasServiceFactory.create(gatewayServices, ALIAS_SERVICE, config, options, ZookeeperRemoteAliasService.class.getName()); + + if (createdService == null) { + throw new ServiceLifecycleException("aliasServiceFactory.create() returned null - cannot create ZookeeperRemoteAliasService"); + } + + if (!(createdService instanceof ZookeeperRemoteAliasService)) { + throw new ServiceLifecycleException("aliasServiceFactory.create() returned unexpected type: " + createdService.getClass().getName() + + ", expected: ZookeeperRemoteAliasService"); + } + + final ZookeeperRemoteAliasService zookeeperAliasService = (ZookeeperRemoteAliasService) createdService; + + options.put(ZookeeperRemoteAliasService.OPTION_NAME_SHOULD_CREATE_TOKENS_SUB_NODE, "true"); options.put(ZookeeperRemoteAliasService.OPTION_NAME_SHOULD_USE_LOCAL_ALIAS, "false"); + + zookeeperAliasService.registerRemoteTokenStateChangeListener(this); zookeeperAliasService.init(config, options); super.setAliasService(zookeeperAliasService); super.init(config, options); + options.remove(ZookeeperRemoteAliasService.OPTION_NAME_SHOULD_CREATE_TOKENS_SUB_NODE); options.remove(ZookeeperRemoteAliasService.OPTION_NAME_SHOULD_USE_LOCAL_ALIAS); } diff --git a/gateway-server/src/main/java/org/apache/knox/gateway/services/topology/impl/DefaultTopologyService.java b/gateway-server/src/main/java/org/apache/knox/gateway/services/topology/impl/DefaultTopologyService.java index 7629bd2acd..02d916f29c 100644 --- a/gateway-server/src/main/java/org/apache/knox/gateway/services/topology/impl/DefaultTopologyService.java +++ b/gateway-server/src/main/java/org/apache/knox/gateway/services/topology/impl/DefaultTopologyService.java @@ -60,12 +60,14 @@ import org.apache.knox.gateway.topology.validation.TopologyValidator; import org.apache.knox.gateway.util.ServiceDefinitionsLoader; import org.apache.knox.gateway.util.TopologyUtils; + +import org.eclipse.persistence.jaxb.JAXBContextFactory; import org.eclipse.persistence.jaxb.JAXBContextProperties; import org.xml.sax.SAXException; -import javax.xml.bind.JAXBContext; -import javax.xml.bind.JAXBException; -import javax.xml.bind.Marshaller; +import jakarta.xml.bind.JAXBContext; +import jakarta.xml.bind.JAXBException; +import jakarta.xml.bind.Marshaller; import java.io.File; import java.io.FileFilter; import java.io.IOException; @@ -116,10 +118,15 @@ private static JAXBContext getJAXBContext() { String pkgName = Topology.class.getPackage().getName(); String bindingFile = pkgName.replace(".", "/") + "/topology_binding-xml.xml"; - Map properties = new HashMap<>(1); - properties.put(JAXBContextProperties.OXM_METADATA_SOURCE, bindingFile); + + Map props = new HashMap<>(); + props.put(JAXBContextProperties.OXM_METADATA_SOURCE, bindingFile); + props.put(JAXBContextProperties.MEDIA_TYPE, "application/xml"); // if you need it + try { - return JAXBContext.newInstance(pkgName, Topology.class.getClassLoader(), properties); + //return JAXBContext.newInstance(pkgName, Topology.class.getClassLoader(), props); + //return JAXBContext.newInstance(Topology.class); + return JAXBContextFactory.createContext(pkgName, Topology.class.getClassLoader(), props); } catch (JAXBException e) { throw new IllegalStateException(e); } diff --git a/gateway-server/src/main/java/org/apache/knox/gateway/util/KnoxCLI.java b/gateway-server/src/main/java/org/apache/knox/gateway/util/KnoxCLI.java index 14653d3715..a64b743ff0 100644 --- a/gateway-server/src/main/java/org/apache/knox/gateway/util/KnoxCLI.java +++ b/gateway-server/src/main/java/org/apache/knox/gateway/util/KnoxCLI.java @@ -933,7 +933,7 @@ private boolean isForceRequired(GatewayConfig config, KeystoreService ks) { if (!X509CertificateUtil.isSelfSignedCertificate(certificate)) { // The relevant certificate exists and is not self-signed: --force is required return true; - } else if (!((X509Certificate) certificate).getSubjectDN().getName().matches(".*?,\\s*OU=Test,\\s*O=Hadoop,\\s*L=Test,\\s*ST=Test,\\s*C=US")) { + } else if (!((X509Certificate) certificate).getSubjectX500Principal().getName().matches(".*?,\\s*OU=Test,\\s*O=Hadoop,\\s*L=Test,\\s*ST=Test,\\s*C=US")) { // The subject name of certificate does not end with "OU=Test,O=Hadoop,L=Test,ST=Test,C=US": --force is required return true; } diff --git a/gateway-server/src/main/java/org/apache/knox/gateway/util/ServiceDefinitionsLoader.java b/gateway-server/src/main/java/org/apache/knox/gateway/util/ServiceDefinitionsLoader.java index 36492c6378..b52b491cd8 100644 --- a/gateway-server/src/main/java/org/apache/knox/gateway/util/ServiceDefinitionsLoader.java +++ b/gateway-server/src/main/java/org/apache/knox/gateway/util/ServiceDefinitionsLoader.java @@ -31,9 +31,9 @@ import org.apache.knox.gateway.service.definition.ServiceDefinitionPair; import org.apache.knox.gateway.service.definition.ServiceDefinitionPairComparator; -import javax.xml.bind.JAXBContext; -import javax.xml.bind.JAXBException; -import javax.xml.bind.Unmarshaller; +import jakarta.xml.bind.JAXBContext; +import jakarta.xml.bind.JAXBException; +import jakarta.xml.bind.Unmarshaller; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; diff --git a/gateway-server/src/main/java/org/apache/knox/gateway/util/TopologyToDescriptor.java b/gateway-server/src/main/java/org/apache/knox/gateway/util/TopologyToDescriptor.java index 0d3c67f9a3..ffb848c25a 100644 --- a/gateway-server/src/main/java/org/apache/knox/gateway/util/TopologyToDescriptor.java +++ b/gateway-server/src/main/java/org/apache/knox/gateway/util/TopologyToDescriptor.java @@ -29,9 +29,9 @@ import org.xml.sax.SAXException; import javax.xml.XMLConstants; -import javax.xml.bind.JAXBContext; -import javax.xml.bind.JAXBException; -import javax.xml.bind.Unmarshaller; +import jakarta.xml.bind.JAXBContext; +import jakarta.xml.bind.JAXBException; +import jakarta.xml.bind.Unmarshaller; import javax.xml.transform.Source; import javax.xml.transform.stream.StreamSource; import javax.xml.validation.Schema; diff --git a/gateway-server/src/test/java/org/apache/knox/gateway/services/security/impl/DefaultKeystoreServiceTest.java b/gateway-server/src/test/java/org/apache/knox/gateway/services/security/impl/DefaultKeystoreServiceTest.java index d65ba802d3..5e85444948 100644 --- a/gateway-server/src/test/java/org/apache/knox/gateway/services/security/impl/DefaultKeystoreServiceTest.java +++ b/gateway-server/src/test/java/org/apache/knox/gateway/services/security/impl/DefaultKeystoreServiceTest.java @@ -742,7 +742,7 @@ private void testAddSelfSignedCertForGateway(String hostname) throws Exception { if (hostname == null) { alias = "test_localhost"; password = "test_localhost".toCharArray(); - expectedSubjectName = "CN=localhost, OU=Test, O=Hadoop, L=Test, ST=Test, C=US"; + expectedSubjectName = "C=US,ST=Test,L=Test,O=Hadoop,OU=Test,CN=localhost"; keystoreService.addSelfSignedCertForGateway(alias, password); } else { @@ -750,9 +750,9 @@ private void testAddSelfSignedCertForGateway(String hostname) throws Exception { password = ("test_" + hostname).toCharArray(); if ("hostname".equals(hostname)) { - expectedSubjectName = "CN=" + InetAddress.getLocalHost().getHostName() + ", OU=Test, O=Hadoop, L=Test, ST=Test, C=US"; + expectedSubjectName = "C=US,ST=Test,L=Test,O=Hadoop,OU=Test,"+"CN=" + InetAddress.getLocalHost().getHostName(); } else { - expectedSubjectName = "CN=" + hostname + ", OU=Test, O=Hadoop, L=Test, ST=Test, C=US"; + expectedSubjectName = "C=US,ST=Test,L=Test,O=Hadoop,OU=Test,"+"CN=" + hostname; } keystoreService.addSelfSignedCertForGateway(alias, password, hostname); @@ -767,8 +767,13 @@ private void testAddSelfSignedCertForGateway(String hostname) throws Exception { Certificate certificate = keystore.getCertificate(alias); assertTrue(certificate instanceof X509Certificate); - Principal subject = ((X509Certificate) certificate).getSubjectDN(); - assertEquals(expectedSubjectName, subject.getName()); + Principal subject = ((X509Certificate) certificate).getSubjectX500Principal(); + // JDK 17 changed the DN format to be more compact (no spaces around commas) + // Handle both old and new formats for compatibility + String actualName = subject.getName(); + String expectedCompact = expectedSubjectName.replace(", ", ","); + assertTrue("Expected: " + expectedSubjectName + " or " + expectedCompact + ", but got: " + actualName, + actualName.equals(expectedSubjectName) || actualName.equals(expectedCompact)); verify(masterService); } diff --git a/gateway-server/src/test/java/org/apache/knox/gateway/services/token/impl/ZookeeperTokenStateServiceTest.java b/gateway-server/src/test/java/org/apache/knox/gateway/services/token/impl/ZookeeperTokenStateServiceTest.java index 59dd184382..2b8e32d1fd 100644 --- a/gateway-server/src/test/java/org/apache/knox/gateway/services/token/impl/ZookeeperTokenStateServiceTest.java +++ b/gateway-server/src/test/java/org/apache/knox/gateway/services/token/impl/ZookeeperTokenStateServiceTest.java @@ -76,8 +76,9 @@ public static void configureAndStartZKCluster() throws Exception { Properties configuration = new Properties(); int port = TestUtils.findFreePort(); configuration.setProperty("clientPort", String.valueOf(port)); - configuration.put("authProvider.1", "org.apache.zookeeper.server.auth.SASLAuthenticationProvider"); - configuration.put("requireClientAuthScheme", "sasl"); + // Removed SASL authentication to fix JDK 17 compatibility issues + // configuration.put("authProvider.1", "org.apache.zookeeper.server.auth.SASLAuthenticationProvider"); + // configuration.put("requireClientAuthScheme", "sasl"); configuration.put("admin.enableServer", "false"); zkServer = ZooKeeperServerEmbedded .builder() @@ -196,6 +197,10 @@ private ZookeeperTokenStateService setupZkTokenStateService(long persistenceInte // mocking GatewayConfig final GatewayConfig gc = EasyMock.createNiceMock(GatewayConfig.class); expect(gc.getRemoteRegistryConfigurationNames()).andReturn(Collections.singletonList(CONFIG_MONITOR_NAME)).anyTimes(); + // Add null check to prevent NullPointerException if Zookeeper server failed to start + if (zkServer == null) { + throw new IllegalStateException("Zookeeper server failed to start in @BeforeClass"); + } final String registryConfig = REMOTE_CONFIG_REGISTRY_TYPE + "=" + ZooKeeperClientService.TYPE + ";" + REMOTE_CONFIG_REGISTRY_ADDRESS + "=" + zkServer.getConnectionString(); expect(gc.getRemoteRegistryConfiguration(CONFIG_MONITOR_NAME)).andReturn(registryConfig).anyTimes(); expect(gc.getRemoteConfigurationMonitorClientName()).andReturn(CONFIG_MONITOR_NAME).anyTimes(); @@ -205,6 +210,7 @@ private ZookeeperTokenStateService setupZkTokenStateService(long persistenceInte final Path baseFolder = Paths.get(testFolder.newFolder().getAbsolutePath()); expect(gc.getGatewayDataDir()).andReturn(Paths.get(baseFolder.toString(), "data").toString()).anyTimes(); expect(gc.getGatewayKeystoreDir()).andReturn(Paths.get(baseFolder.toString(), "data", "keystores").toString()).anyTimes(); + expect(gc.getGatewaySecurityDir()).andReturn(Paths.get(baseFolder.toString(), "security").toString()).anyTimes(); replay(gc); // mocking GatewayServices diff --git a/gateway-service-admin/pom.xml b/gateway-service-admin/pom.xml index c2b1449859..c9b49ac323 100644 --- a/gateway-service-admin/pom.xml +++ b/gateway-service-admin/pom.xml @@ -53,10 +53,6 @@ org.apache.knox gateway-service-definitions - - org.eclipse.persistence - eclipselink - javax.json javax.json-api @@ -65,6 +61,14 @@ org.glassfish javax.json + + jakarta.json + jakarta.json-api + + + org.eclipse.parsson + parsson + org.glassfish.hk2.external javax.inject @@ -89,17 +93,19 @@ - javax.xml.bind - jaxb-api + jakarta.xml.bind + jakarta.xml.bind-api + com.fasterxml.jackson.core jackson-databind @@ -109,6 +115,11 @@ swagger-annotations + + org.eclipse.persistence + org.eclipse.persistence.moxy + + org.apache.knox gateway-test-utils diff --git a/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/HrefListingMarshaller.java b/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/HrefListingMarshaller.java index 878792b130..ba0e7acb2d 100644 --- a/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/HrefListingMarshaller.java +++ b/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/HrefListingMarshaller.java @@ -24,9 +24,9 @@ import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.ext.MessageBodyWriter; import javax.ws.rs.ext.Provider; -import javax.xml.bind.JAXBContext; -import javax.xml.bind.JAXBException; -import javax.xml.bind.Marshaller; +import jakarta.xml.bind.JAXBContext; +import jakarta.xml.bind.JAXBException; +import jakarta.xml.bind.Marshaller; import java.io.IOException; import java.io.OutputStream; import java.lang.annotation.Annotation; @@ -72,4 +72,4 @@ public void writeTo(TopologiesResource.HrefListing instance, } } -} \ No newline at end of file +} diff --git a/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/ServiceDefinitionCollectionMarshaller.java b/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/ServiceDefinitionCollectionMarshaller.java index 2bc8477c77..4e0e84d1b9 100644 --- a/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/ServiceDefinitionCollectionMarshaller.java +++ b/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/ServiceDefinitionCollectionMarshaller.java @@ -30,8 +30,8 @@ import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.ext.MessageBodyWriter; import javax.ws.rs.ext.Provider; -import javax.xml.bind.JAXBException; -import javax.xml.bind.Marshaller; +import jakarta.xml.bind.JAXBException; +import jakarta.xml.bind.Marshaller; import org.apache.knox.gateway.service.admin.ServiceDefinitionsResource.ServiceDefinitionsWrapper; import org.eclipse.persistence.jaxb.JAXBContextFactory; diff --git a/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/ServiceDefinitionUnmarshaller.java b/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/ServiceDefinitionUnmarshaller.java index 6e15b7e991..30bf9a838a 100644 --- a/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/ServiceDefinitionUnmarshaller.java +++ b/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/ServiceDefinitionUnmarshaller.java @@ -28,9 +28,9 @@ import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.ext.MessageBodyReader; import javax.ws.rs.ext.Provider; -import javax.xml.bind.JAXBContext; -import javax.xml.bind.JAXBException; -import javax.xml.bind.Unmarshaller; +import jakarta.xml.bind.JAXBContext; +import jakarta.xml.bind.JAXBException; +import jakarta.xml.bind.Unmarshaller; import org.apache.knox.gateway.service.definition.ServiceDefinitionPair; diff --git a/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/ServiceDefinitionsResource.java b/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/ServiceDefinitionsResource.java index 15bb6a78f7..55d41c9739 100644 --- a/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/ServiceDefinitionsResource.java +++ b/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/ServiceDefinitionsResource.java @@ -44,10 +44,10 @@ import javax.ws.rs.QueryParam; import javax.ws.rs.core.Context; import javax.ws.rs.core.Response; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlElementWrapper; +import jakarta.xml.bind.annotation.XmlAccessType; +import jakarta.xml.bind.annotation.XmlAccessorType; +import jakarta.xml.bind.annotation.XmlElement; +import jakarta.xml.bind.annotation.XmlElementWrapper; import org.apache.knox.gateway.service.definition.ServiceDefinitionPair; import org.apache.knox.gateway.service.definition.ServiceDefinitionPairComparator; diff --git a/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/ServiceDiscoveryCollectionMarshaller.java b/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/ServiceDiscoveryCollectionMarshaller.java index 6f93cd473b..9e86cb613c 100644 --- a/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/ServiceDiscoveryCollectionMarshaller.java +++ b/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/ServiceDiscoveryCollectionMarshaller.java @@ -31,9 +31,9 @@ import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.ext.MessageBodyWriter; import javax.ws.rs.ext.Provider; -import javax.xml.bind.JAXBContext; -import javax.xml.bind.JAXBException; -import javax.xml.bind.Marshaller; +import jakarta.xml.bind.JAXBContext; +import jakarta.xml.bind.JAXBException; +import jakarta.xml.bind.Marshaller; import org.apache.knox.gateway.service.admin.ServiceDiscoveryResource.ServiceDiscoveryWrapper; import org.eclipse.persistence.jaxb.JAXBContextProperties; diff --git a/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/ServiceDiscoveryResource.java b/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/ServiceDiscoveryResource.java index dea9bd6510..4209a210a4 100644 --- a/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/ServiceDiscoveryResource.java +++ b/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/ServiceDiscoveryResource.java @@ -28,10 +28,10 @@ import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.Produces; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlElementWrapper; +import jakarta.xml.bind.annotation.XmlAccessType; +import jakarta.xml.bind.annotation.XmlAccessorType; +import jakarta.xml.bind.annotation.XmlElement; +import jakarta.xml.bind.annotation.XmlElementWrapper; import org.apache.knox.gateway.topology.discovery.ServiceDiscovery; import org.apache.knox.gateway.topology.discovery.ServiceDiscoveryFactory; diff --git a/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/TopologiesResource.java b/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/TopologiesResource.java index 7a6ec5b4d2..2c66faafd2 100644 --- a/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/TopologiesResource.java +++ b/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/TopologiesResource.java @@ -47,10 +47,10 @@ import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlElementWrapper; +import jakarta.xml.bind.annotation.XmlAccessType; +import jakarta.xml.bind.annotation.XmlAccessorType; +import jakarta.xml.bind.annotation.XmlElement; +import jakarta.xml.bind.annotation.XmlElementWrapper; import java.io.File; import java.io.IOException; import java.net.URI; diff --git a/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/TopologyCollectionMarshaller.java b/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/TopologyCollectionMarshaller.java index cb2158f356..308394b75a 100644 --- a/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/TopologyCollectionMarshaller.java +++ b/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/TopologyCollectionMarshaller.java @@ -28,9 +28,9 @@ import javax.ws.rs.ext.MessageBodyWriter; import javax.ws.rs.ext.Provider; import javax.ws.rs.ext.Providers; -import javax.xml.bind.JAXBContext; -import javax.xml.bind.JAXBException; -import javax.xml.bind.Marshaller; +import jakarta.xml.bind.JAXBContext; +import jakarta.xml.bind.JAXBException; +import jakarta.xml.bind.Marshaller; import java.io.IOException; import java.io.OutputStream; import java.lang.annotation.Annotation; @@ -69,4 +69,4 @@ public void writeTo(TopologiesResource.SimpleTopologyWrapper instance, Class throw new IOException(e); } } -} \ No newline at end of file +} diff --git a/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/TopologyMarshaller.java b/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/TopologyMarshaller.java index ed06a94863..e91e02a4a8 100644 --- a/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/TopologyMarshaller.java +++ b/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/TopologyMarshaller.java @@ -30,10 +30,10 @@ import javax.ws.rs.ext.MessageBodyReader; import javax.ws.rs.ext.MessageBodyWriter; import javax.ws.rs.ext.Provider; -import javax.xml.bind.JAXBContext; -import javax.xml.bind.JAXBException; -import javax.xml.bind.Marshaller; -import javax.xml.bind.Unmarshaller; +import jakarta.xml.bind.JAXBContext; +import jakarta.xml.bind.JAXBException; +import jakarta.xml.bind.Marshaller; +import jakarta.xml.bind.Unmarshaller; import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamReader; diff --git a/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/VersionMarshaller.java b/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/VersionMarshaller.java index 9344c7ecf3..6cf87fd0a6 100644 --- a/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/VersionMarshaller.java +++ b/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/VersionMarshaller.java @@ -28,9 +28,9 @@ import javax.ws.rs.ext.MessageBodyWriter; import javax.ws.rs.ext.Provider; import javax.ws.rs.ext.Providers; -import javax.xml.bind.JAXBContext; -import javax.xml.bind.JAXBException; -import javax.xml.bind.Marshaller; +import jakarta.xml.bind.JAXBContext; +import jakarta.xml.bind.JAXBException; +import jakarta.xml.bind.Marshaller; import java.io.IOException; import java.io.OutputStream; import java.lang.annotation.Annotation; @@ -69,4 +69,4 @@ public void writeTo(VersionResource.ServerVersion instance, Class type, Type throw new IOException(e); } } -} \ No newline at end of file +} diff --git a/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/VersionResource.java b/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/VersionResource.java index 38972a50b7..03d716c248 100644 --- a/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/VersionResource.java +++ b/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/VersionResource.java @@ -23,8 +23,8 @@ import javax.ws.rs.Produces; import javax.ws.rs.core.Context; import javax.ws.rs.core.Response; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; +import jakarta.xml.bind.annotation.XmlElement; +import jakarta.xml.bind.annotation.XmlRootElement; import org.apache.knox.gateway.services.ServiceType; diff --git a/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/beans/Application.java b/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/beans/Application.java index 01145e17c2..082f92f6d0 100644 --- a/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/beans/Application.java +++ b/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/beans/Application.java @@ -17,8 +17,8 @@ */ package org.apache.knox.gateway.service.admin.beans; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; +import jakarta.xml.bind.annotation.XmlAccessType; +import jakarta.xml.bind.annotation.XmlAccessorType; @XmlAccessorType(XmlAccessType.NONE) public class Application extends Service { diff --git a/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/beans/Param.java b/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/beans/Param.java index 337c1f332e..a8bc010674 100644 --- a/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/beans/Param.java +++ b/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/beans/Param.java @@ -17,9 +17,9 @@ */ package org.apache.knox.gateway.service.admin.beans; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; +import jakarta.xml.bind.annotation.XmlAccessType; +import jakarta.xml.bind.annotation.XmlAccessorType; +import jakarta.xml.bind.annotation.XmlElement; @XmlAccessorType(XmlAccessType.NONE) public class Param { diff --git a/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/beans/Provider.java b/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/beans/Provider.java index ffee998aca..3c5c3c569d 100644 --- a/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/beans/Provider.java +++ b/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/beans/Provider.java @@ -17,9 +17,9 @@ */ package org.apache.knox.gateway.service.admin.beans; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; +import jakarta.xml.bind.annotation.XmlAccessType; +import jakarta.xml.bind.annotation.XmlAccessorType; +import jakarta.xml.bind.annotation.XmlElement; import java.util.ArrayList; import java.util.List; diff --git a/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/beans/Service.java b/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/beans/Service.java index 26b934bced..21e6cf4b95 100644 --- a/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/beans/Service.java +++ b/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/beans/Service.java @@ -17,9 +17,9 @@ */ package org.apache.knox.gateway.service.admin.beans; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; +import jakarta.xml.bind.annotation.XmlAccessType; +import jakarta.xml.bind.annotation.XmlAccessorType; +import jakarta.xml.bind.annotation.XmlElement; import java.util.ArrayList; import java.util.List; diff --git a/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/beans/Topology.java b/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/beans/Topology.java index b519b89b28..00f9e7d1fb 100644 --- a/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/beans/Topology.java +++ b/gateway-service-admin/src/main/java/org/apache/knox/gateway/service/admin/beans/Topology.java @@ -17,9 +17,9 @@ */ package org.apache.knox.gateway.service.admin.beans; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlElementWrapper; -import javax.xml.bind.annotation.XmlRootElement; +import jakarta.xml.bind.annotation.XmlElement; +import jakarta.xml.bind.annotation.XmlElementWrapper; +import jakarta.xml.bind.annotation.XmlRootElement; import java.net.URI; import java.util.ArrayList; import java.util.List; diff --git a/gateway-service-admin/src/test/java/org/apache/knox/gateway/service/admin/TopologyMarshallerTest.java b/gateway-service-admin/src/test/java/org/apache/knox/gateway/service/admin/TopologyMarshallerTest.java index 6fe355b98a..3ac394593a 100644 --- a/gateway-service-admin/src/test/java/org/apache/knox/gateway/service/admin/TopologyMarshallerTest.java +++ b/gateway-service-admin/src/test/java/org/apache/knox/gateway/service/admin/TopologyMarshallerTest.java @@ -20,8 +20,8 @@ import java.io.StringWriter; import java.util.HashMap; import java.util.Map; -import javax.xml.bind.JAXBContext; -import javax.xml.bind.Marshaller; +import jakarta.xml.bind.JAXBContext; +import jakarta.xml.bind.Marshaller; import org.apache.knox.gateway.topology.Application; import org.apache.knox.gateway.topology.Topology; @@ -58,4 +58,4 @@ public void testTopologyMarshalling() throws Exception { assertThat( the( xml ), hasXPath( "/topology/application/name", returningAString(), is("test-app-name") ) ); } -} \ No newline at end of file +} diff --git a/gateway-service-auth/pom.xml b/gateway-service-auth/pom.xml index 26aecbdb27..0231b80adb 100644 --- a/gateway-service-auth/pom.xml +++ b/gateway-service-auth/pom.xml @@ -62,4 +62,16 @@ + + + + org.apache.maven.plugins + maven-surefire-plugin + + --add-opens java.base/java.util=ALL-UNNAMED + + + + + diff --git a/gateway-service-definitions/pom.xml b/gateway-service-definitions/pom.xml index 403cbe075b..b44fcdc32f 100644 --- a/gateway-service-definitions/pom.xml +++ b/gateway-service-definitions/pom.xml @@ -30,31 +30,32 @@ The service definitions aka stacks. + + jakarta.xml.bind + jakarta.xml.bind-api + jakarta.activation jakarta.activation-api - + - com.sun.xml.bind - jaxb-core + org.eclipse.persistence + org.eclipse.persistence.moxy - com.sun.xml.bind - jaxb-impl + com.sun.activation + jakarta.activation org.apache.commons commons-lang3 - - org.eclipse.persistence - eclipselink - javax.json javax.json-api @@ -63,6 +64,14 @@ org.glassfish javax.json + + jakarta.json + jakarta.json-api + + + org.eclipse.parsson + parsson + org.apache.knox gateway-test-utils diff --git a/gateway-service-definitions/src/main/java/org/apache/knox/gateway/service/definition/CustomDispatch.java b/gateway-service-definitions/src/main/java/org/apache/knox/gateway/service/definition/CustomDispatch.java index bd5bd1d2ca..35b39e5882 100644 --- a/gateway-service-definitions/src/main/java/org/apache/knox/gateway/service/definition/CustomDispatch.java +++ b/gateway-service-definitions/src/main/java/org/apache/knox/gateway/service/definition/CustomDispatch.java @@ -17,11 +17,11 @@ */ package org.apache.knox.gateway.service.definition; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlType; +import jakarta.xml.bind.annotation.XmlAccessType; +import jakarta.xml.bind.annotation.XmlAccessorType; +import jakarta.xml.bind.annotation.XmlAttribute; +import jakarta.xml.bind.annotation.XmlElement; +import jakarta.xml.bind.annotation.XmlType; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; diff --git a/gateway-service-definitions/src/main/java/org/apache/knox/gateway/service/definition/Metadata.java b/gateway-service-definitions/src/main/java/org/apache/knox/gateway/service/definition/Metadata.java index ed9d7e339c..3ca2114b98 100644 --- a/gateway-service-definitions/src/main/java/org/apache/knox/gateway/service/definition/Metadata.java +++ b/gateway-service-definitions/src/main/java/org/apache/knox/gateway/service/definition/Metadata.java @@ -19,9 +19,9 @@ import java.util.List; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlElementWrapper; -import javax.xml.bind.annotation.XmlType; +import jakarta.xml.bind.annotation.XmlElement; +import jakarta.xml.bind.annotation.XmlElementWrapper; +import jakarta.xml.bind.annotation.XmlType; import org.apache.commons.lang3.builder.EqualsBuilder; import org.apache.commons.lang3.builder.HashCodeBuilder; diff --git a/gateway-service-definitions/src/main/java/org/apache/knox/gateway/service/definition/Policy.java b/gateway-service-definitions/src/main/java/org/apache/knox/gateway/service/definition/Policy.java index adbb0addf4..0c3995c70f 100644 --- a/gateway-service-definitions/src/main/java/org/apache/knox/gateway/service/definition/Policy.java +++ b/gateway-service-definitions/src/main/java/org/apache/knox/gateway/service/definition/Policy.java @@ -17,8 +17,8 @@ */ package org.apache.knox.gateway.service.definition; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlElement; +import jakarta.xml.bind.annotation.XmlAttribute; +import jakarta.xml.bind.annotation.XmlElement; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; diff --git a/gateway-service-definitions/src/main/java/org/apache/knox/gateway/service/definition/Rewrite.java b/gateway-service-definitions/src/main/java/org/apache/knox/gateway/service/definition/Rewrite.java index 3a9292c0d8..9a39eaf0fb 100644 --- a/gateway-service-definitions/src/main/java/org/apache/knox/gateway/service/definition/Rewrite.java +++ b/gateway-service-definitions/src/main/java/org/apache/knox/gateway/service/definition/Rewrite.java @@ -17,8 +17,8 @@ */ package org.apache.knox.gateway.service.definition; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlType; +import jakarta.xml.bind.annotation.XmlAttribute; +import jakarta.xml.bind.annotation.XmlType; @XmlType(name = "rewrite") public class Rewrite { diff --git a/gateway-service-definitions/src/main/java/org/apache/knox/gateway/service/definition/Route.java b/gateway-service-definitions/src/main/java/org/apache/knox/gateway/service/definition/Route.java index c560a38336..db19957383 100644 --- a/gateway-service-definitions/src/main/java/org/apache/knox/gateway/service/definition/Route.java +++ b/gateway-service-definitions/src/main/java/org/apache/knox/gateway/service/definition/Route.java @@ -17,10 +17,10 @@ */ package org.apache.knox.gateway.service.definition; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlElementWrapper; -import javax.xml.bind.annotation.XmlType; +import jakarta.xml.bind.annotation.XmlAttribute; +import jakarta.xml.bind.annotation.XmlElement; +import jakarta.xml.bind.annotation.XmlElementWrapper; +import jakarta.xml.bind.annotation.XmlType; import java.util.List; @XmlType(name = "route") diff --git a/gateway-service-definitions/src/main/java/org/apache/knox/gateway/service/definition/Sample.java b/gateway-service-definitions/src/main/java/org/apache/knox/gateway/service/definition/Sample.java index b69bce3dc2..0f365f1d49 100644 --- a/gateway-service-definitions/src/main/java/org/apache/knox/gateway/service/definition/Sample.java +++ b/gateway-service-definitions/src/main/java/org/apache/knox/gateway/service/definition/Sample.java @@ -17,8 +17,8 @@ */ package org.apache.knox.gateway.service.definition; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlType; +import jakarta.xml.bind.annotation.XmlElement; +import jakarta.xml.bind.annotation.XmlType; @XmlType(name = "sample") public class Sample { diff --git a/gateway-service-definitions/src/main/java/org/apache/knox/gateway/service/definition/ServiceDefinition.java b/gateway-service-definitions/src/main/java/org/apache/knox/gateway/service/definition/ServiceDefinition.java index 4da0976d7c..e59cbbb878 100644 --- a/gateway-service-definitions/src/main/java/org/apache/knox/gateway/service/definition/ServiceDefinition.java +++ b/gateway-service-definitions/src/main/java/org/apache/knox/gateway/service/definition/ServiceDefinition.java @@ -17,10 +17,10 @@ */ package org.apache.knox.gateway.service.definition; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlElementWrapper; -import javax.xml.bind.annotation.XmlRootElement; +import jakarta.xml.bind.annotation.XmlAttribute; +import jakarta.xml.bind.annotation.XmlElement; +import jakarta.xml.bind.annotation.XmlElementWrapper; +import jakarta.xml.bind.annotation.XmlRootElement; import java.util.List; diff --git a/gateway-service-definitions/src/test/java/org/apache/knox/gateway/service/definition/ServiceDefinitionTest.java b/gateway-service-definitions/src/test/java/org/apache/knox/gateway/service/definition/ServiceDefinitionTest.java index aac7c8078d..87bf07b6d3 100644 --- a/gateway-service-definitions/src/test/java/org/apache/knox/gateway/service/definition/ServiceDefinitionTest.java +++ b/gateway-service-definitions/src/test/java/org/apache/knox/gateway/service/definition/ServiceDefinitionTest.java @@ -19,8 +19,8 @@ import org.junit.Test; -import javax.xml.bind.JAXBContext; -import javax.xml.bind.Unmarshaller; +import jakarta.xml.bind.JAXBContext; +import jakarta.xml.bind.Unmarshaller; import java.net.URL; import java.util.List; diff --git a/gateway-service-hashicorp-vault/pom.xml b/gateway-service-hashicorp-vault/pom.xml index cd54f37daf..0f7f8788ee 100644 --- a/gateway-service-hashicorp-vault/pom.xml +++ b/gateway-service-hashicorp-vault/pom.xml @@ -56,6 +56,7 @@ org.slf4j slf4j-api + test diff --git a/gateway-service-hbase/pom.xml b/gateway-service-hbase/pom.xml index b57ece8470..d60014b094 100644 --- a/gateway-service-hbase/pom.xml +++ b/gateway-service-hbase/pom.xml @@ -50,6 +50,10 @@ org.apache.httpcomponents httpclient + + org.apache.httpcomponents + httpcore + org.apache.knox gateway-test-utils diff --git a/gateway-service-hive/pom.xml b/gateway-service-hive/pom.xml index 933b3b9cac..374652f387 100644 --- a/gateway-service-hive/pom.xml +++ b/gateway-service-hive/pom.xml @@ -56,6 +56,10 @@ org.apache.httpcomponents httpclient + + org.apache.httpcomponents + httpcore + org.apache.knox diff --git a/gateway-service-impala/pom.xml b/gateway-service-impala/pom.xml index c417b7a764..7936adf1ed 100644 --- a/gateway-service-impala/pom.xml +++ b/gateway-service-impala/pom.xml @@ -56,6 +56,10 @@ org.apache.httpcomponents httpclient + + org.apache.httpcomponents + httpcore + org.apache.knox diff --git a/gateway-service-knoxtoken/pom.xml b/gateway-service-knoxtoken/pom.xml index 5e5116afa3..f957f9bfca 100644 --- a/gateway-service-knoxtoken/pom.xml +++ b/gateway-service-knoxtoken/pom.xml @@ -105,6 +105,10 @@ com.google.code.gson gson + + de.thetaphi + forbiddenapis + org.apache.knox diff --git a/gateway-service-knoxtoken/src/main/java/org/apache/knox/gateway/service/knoxtoken/TokenResource.java b/gateway-service-knoxtoken/src/main/java/org/apache/knox/gateway/service/knoxtoken/TokenResource.java index 82ba55fa6f..b7122706e0 100644 --- a/gateway-service-knoxtoken/src/main/java/org/apache/knox/gateway/service/knoxtoken/TokenResource.java +++ b/gateway-service-knoxtoken/src/main/java/org/apache/knox/gateway/service/knoxtoken/TokenResource.java @@ -65,6 +65,9 @@ import com.nimbusds.jose.KeyLengthException; import com.nimbusds.jose.crypto.MACSigner; import com.nimbusds.jose.util.ByteUtils; + +import de.thetaphi.forbiddenapis.SuppressForbidden; + import org.apache.commons.codec.binary.Base64; import org.apache.commons.lang3.StringUtils; import org.apache.knox.gateway.config.GatewayConfig; @@ -992,7 +995,7 @@ protected Response enforceClientCertIfRequired() { if (clientCertRequired) { X509Certificate cert = extractCertificate(request); if (cert != null) { - if (!allowedDNs.contains(cert.getSubjectDN().getName().replaceAll("\\s+", ""))) { + if (!allowedDNs.contains(cert.getSubjectX500Principal().getName().replaceAll("\\s+", ""))) { response = Response.status(Response.Status.FORBIDDEN) .entity("{ \"Unable to get token - untrusted client cert.\" }") .build(); @@ -1100,6 +1103,7 @@ private boolean shouldIncludeGroups() { return Boolean.parseBoolean(request.getParameter(KNOX_TOKEN_INCLUDE_GROUPS)); } + @SuppressForbidden protected Set groups() { Subject subject = Subject.getSubject(AccessController.getContext()); Set groups = subject.getPrincipals(GroupPrincipal.class).stream() diff --git a/gateway-service-knoxtoken/src/test/java/org/apache/knox/gateway/service/knoxtoken/TokenServiceResourceTest.java b/gateway-service-knoxtoken/src/test/java/org/apache/knox/gateway/service/knoxtoken/TokenServiceResourceTest.java index 13355a994a..8f6572ef99 100644 --- a/gateway-service-knoxtoken/src/test/java/org/apache/knox/gateway/service/knoxtoken/TokenServiceResourceTest.java +++ b/gateway-service-knoxtoken/src/test/java/org/apache/knox/gateway/service/knoxtoken/TokenServiceResourceTest.java @@ -40,6 +40,7 @@ import java.security.Principal; import java.security.PrivilegedAction; import java.security.cert.X509Certificate; +import javax.security.auth.x500.X500Principal; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.util.AbstractMap; @@ -82,6 +83,7 @@ import com.nimbusds.jose.KeyLengthException; import com.nimbusds.jose.crypto.RSASSASigner; import com.nimbusds.jose.crypto.RSASSAVerifier; +import de.thetaphi.forbiddenapis.SuppressForbidden; import org.apache.commons.codec.digest.HmacAlgorithms; import org.apache.commons.lang3.StringUtils; import org.apache.knox.gateway.config.GatewayConfig; @@ -160,6 +162,7 @@ private void configureCommonExpectations(Map contextExpectations configureCommonExpectations(contextExpectations, null, serverManagedTssEnabled); } + @SuppressForbidden private void configureCommonExpectations(Map contextExpectations, String expectedSubjectDN, Boolean serverManagedTssEnabled) throws Exception { context = EasyMock.createNiceMock(ServletContext.class); contextExpectations.forEach((key, value) -> EasyMock.expect(context.getInitParameter(key)).andReturn(value).anyTimes()); @@ -217,6 +220,7 @@ private void configureCommonExpectations(Map contextExpectations if (StringUtils.isNotBlank(expectedSubjectDN)) { X509Certificate trustedCertMock = EasyMock.createMock(X509Certificate.class); EasyMock.expect(trustedCertMock.getSubjectDN()).andReturn(new PrimaryPrincipal(expectedSubjectDN)).anyTimes(); + EasyMock.expect(trustedCertMock.getSubjectX500Principal()).andReturn(new X500Principal(expectedSubjectDN)).anyTimes(); ArrayList certArrayList = new ArrayList<>(); certArrayList.add(trustedCertMock); X509Certificate[] certs = {}; diff --git a/gateway-service-metadata/pom.xml b/gateway-service-metadata/pom.xml index 397614dcfe..f9adf6fdae 100644 --- a/gateway-service-metadata/pom.xml +++ b/gateway-service-metadata/pom.xml @@ -59,8 +59,8 @@ javax.ws.rs-api - javax.xml.bind - jaxb-api + jakarta.xml.bind + jakarta.xml.bind-api org.apache.commons @@ -68,7 +68,7 @@ org.eclipse.persistence - eclipselink + org.eclipse.persistence.moxy org.glassfish.hk2.external diff --git a/gateway-service-metadata/src/main/java/org/apache/knox/gateway/service/metadata/GeneralProxyInformation.java b/gateway-service-metadata/src/main/java/org/apache/knox/gateway/service/metadata/GeneralProxyInformation.java index 4935c4740f..833f0d3410 100644 --- a/gateway-service-metadata/src/main/java/org/apache/knox/gateway/service/metadata/GeneralProxyInformation.java +++ b/gateway-service-metadata/src/main/java/org/apache/knox/gateway/service/metadata/GeneralProxyInformation.java @@ -17,8 +17,8 @@ */ package org.apache.knox.gateway.service.metadata; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; +import jakarta.xml.bind.annotation.XmlElement; +import jakarta.xml.bind.annotation.XmlRootElement; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; diff --git a/gateway-service-metadata/src/main/java/org/apache/knox/gateway/service/metadata/GeneralProxyInformationMarshaller.java b/gateway-service-metadata/src/main/java/org/apache/knox/gateway/service/metadata/GeneralProxyInformationMarshaller.java index f442d6da1a..205f585b6f 100644 --- a/gateway-service-metadata/src/main/java/org/apache/knox/gateway/service/metadata/GeneralProxyInformationMarshaller.java +++ b/gateway-service-metadata/src/main/java/org/apache/knox/gateway/service/metadata/GeneralProxyInformationMarshaller.java @@ -30,8 +30,8 @@ import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.ext.MessageBodyWriter; import javax.ws.rs.ext.Provider; -import javax.xml.bind.JAXBException; -import javax.xml.bind.Marshaller; +import jakarta.xml.bind.JAXBException; +import jakarta.xml.bind.Marshaller; import org.eclipse.persistence.jaxb.JAXBContextFactory; import org.eclipse.persistence.jaxb.JAXBContextProperties; diff --git a/gateway-service-metadata/src/main/java/org/apache/knox/gateway/service/metadata/ServiceModel.java b/gateway-service-metadata/src/main/java/org/apache/knox/gateway/service/metadata/ServiceModel.java index 600347531e..a3586d3e1f 100644 --- a/gateway-service-metadata/src/main/java/org/apache/knox/gateway/service/metadata/ServiceModel.java +++ b/gateway-service-metadata/src/main/java/org/apache/knox/gateway/service/metadata/ServiceModel.java @@ -31,11 +31,11 @@ import java.util.TreeSet; import javax.servlet.http.HttpServletRequest; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlElementWrapper; -import javax.xml.bind.annotation.XmlRootElement; +import jakarta.xml.bind.annotation.XmlAccessType; +import jakarta.xml.bind.annotation.XmlAccessorType; +import jakarta.xml.bind.annotation.XmlElement; +import jakarta.xml.bind.annotation.XmlElementWrapper; +import jakarta.xml.bind.annotation.XmlRootElement; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.builder.EqualsBuilder; diff --git a/gateway-service-metadata/src/main/java/org/apache/knox/gateway/service/metadata/TopologyInformation.java b/gateway-service-metadata/src/main/java/org/apache/knox/gateway/service/metadata/TopologyInformation.java index 7bfb0c649f..39fe4b431d 100644 --- a/gateway-service-metadata/src/main/java/org/apache/knox/gateway/service/metadata/TopologyInformation.java +++ b/gateway-service-metadata/src/main/java/org/apache/knox/gateway/service/metadata/TopologyInformation.java @@ -19,9 +19,9 @@ import java.util.Set; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlElementWrapper; -import javax.xml.bind.annotation.XmlRootElement; +import jakarta.xml.bind.annotation.XmlElement; +import jakarta.xml.bind.annotation.XmlElementWrapper; +import jakarta.xml.bind.annotation.XmlRootElement; @XmlRootElement(name = "topology") public class TopologyInformation implements Comparable{ diff --git a/gateway-service-metadata/src/main/java/org/apache/knox/gateway/service/metadata/TopologyInformationWrapper.java b/gateway-service-metadata/src/main/java/org/apache/knox/gateway/service/metadata/TopologyInformationWrapper.java index f27a25673c..30901b5ad7 100644 --- a/gateway-service-metadata/src/main/java/org/apache/knox/gateway/service/metadata/TopologyInformationWrapper.java +++ b/gateway-service-metadata/src/main/java/org/apache/knox/gateway/service/metadata/TopologyInformationWrapper.java @@ -20,10 +20,10 @@ import java.util.Set; import java.util.TreeSet; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlElementWrapper; +import jakarta.xml.bind.annotation.XmlAccessType; +import jakarta.xml.bind.annotation.XmlAccessorType; +import jakarta.xml.bind.annotation.XmlElement; +import jakarta.xml.bind.annotation.XmlElementWrapper; @XmlAccessorType(XmlAccessType.NONE) public class TopologyInformationWrapper { diff --git a/gateway-service-metadata/src/main/java/org/apache/knox/gateway/service/metadata/TopologyInformationWrapperMarshaller.java b/gateway-service-metadata/src/main/java/org/apache/knox/gateway/service/metadata/TopologyInformationWrapperMarshaller.java index 770be12f34..a411459c03 100644 --- a/gateway-service-metadata/src/main/java/org/apache/knox/gateway/service/metadata/TopologyInformationWrapperMarshaller.java +++ b/gateway-service-metadata/src/main/java/org/apache/knox/gateway/service/metadata/TopologyInformationWrapperMarshaller.java @@ -30,8 +30,8 @@ import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.ext.MessageBodyWriter; import javax.ws.rs.ext.Provider; -import javax.xml.bind.JAXBException; -import javax.xml.bind.Marshaller; +import jakarta.xml.bind.JAXBException; +import jakarta.xml.bind.Marshaller; import org.eclipse.persistence.jaxb.JAXBContextFactory; import org.eclipse.persistence.jaxb.JAXBContextProperties; diff --git a/gateway-service-remoteconfig/pom.xml b/gateway-service-remoteconfig/pom.xml index c5152dce85..eba7fc18bc 100644 --- a/gateway-service-remoteconfig/pom.xml +++ b/gateway-service-remoteconfig/pom.xml @@ -68,6 +68,7 @@ commons-io commons-io + test @@ -76,17 +77,15 @@ - javax.xml.bind - jaxb-api - - - com.sun.xml.bind - jaxb-core + jakarta.xml.bind + jakarta.xml.bind-api + org.apache.knox diff --git a/gateway-service-remoteconfig/src/main/java/org/apache/knox/gateway/service/config/remote/config/RemoteConfigurationRegistries.java b/gateway-service-remoteconfig/src/main/java/org/apache/knox/gateway/service/config/remote/config/RemoteConfigurationRegistries.java index 58ffebfbef..ef3879c25f 100644 --- a/gateway-service-remoteconfig/src/main/java/org/apache/knox/gateway/service/config/remote/config/RemoteConfigurationRegistries.java +++ b/gateway-service-remoteconfig/src/main/java/org/apache/knox/gateway/service/config/remote/config/RemoteConfigurationRegistries.java @@ -16,8 +16,8 @@ */ package org.apache.knox.gateway.service.config.remote.config; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; +import jakarta.xml.bind.annotation.XmlElement; +import jakarta.xml.bind.annotation.XmlRootElement; import java.util.ArrayList; import java.util.List; diff --git a/gateway-service-remoteconfig/src/main/java/org/apache/knox/gateway/service/config/remote/config/RemoteConfigurationRegistriesParser.java b/gateway-service-remoteconfig/src/main/java/org/apache/knox/gateway/service/config/remote/config/RemoteConfigurationRegistriesParser.java index 82704b54a6..0038e3f53e 100644 --- a/gateway-service-remoteconfig/src/main/java/org/apache/knox/gateway/service/config/remote/config/RemoteConfigurationRegistriesParser.java +++ b/gateway-service-remoteconfig/src/main/java/org/apache/knox/gateway/service/config/remote/config/RemoteConfigurationRegistriesParser.java @@ -18,9 +18,9 @@ import org.apache.knox.gateway.service.config.remote.RemoteConfigurationRegistryConfig; -import javax.xml.bind.JAXBContext; -import javax.xml.bind.JAXBException; -import javax.xml.bind.Unmarshaller; +import jakarta.xml.bind.JAXBContext; +import jakarta.xml.bind.JAXBException; +import jakarta.xml.bind.Unmarshaller; import java.io.File; import java.util.ArrayList; import java.util.List; diff --git a/gateway-service-remoteconfig/src/main/java/org/apache/knox/gateway/service/config/remote/config/RemoteConfigurationRegistry.java b/gateway-service-remoteconfig/src/main/java/org/apache/knox/gateway/service/config/remote/config/RemoteConfigurationRegistry.java index 3be01cea0b..2d756619f3 100644 --- a/gateway-service-remoteconfig/src/main/java/org/apache/knox/gateway/service/config/remote/config/RemoteConfigurationRegistry.java +++ b/gateway-service-remoteconfig/src/main/java/org/apache/knox/gateway/service/config/remote/config/RemoteConfigurationRegistry.java @@ -18,7 +18,7 @@ import org.apache.knox.gateway.service.config.remote.RemoteConfigurationRegistryConfig; -import javax.xml.bind.annotation.XmlElement; +import jakarta.xml.bind.annotation.XmlElement; class RemoteConfigurationRegistry implements RemoteConfigurationRegistryConfig { diff --git a/gateway-service-session/pom.xml b/gateway-service-session/pom.xml index 910d4d97cb..62521481b3 100644 --- a/gateway-service-session/pom.xml +++ b/gateway-service-session/pom.xml @@ -55,8 +55,8 @@ javax.ws.rs-api - javax.xml.bind - jaxb-api + jakarta.xml.bind + jakarta.xml.bind-api org.apache.commons @@ -64,7 +64,7 @@ org.eclipse.persistence - eclipselink + org.eclipse.persistence.moxy org.glassfish.hk2.external diff --git a/gateway-service-session/src/main/java/org/apache/knox/gateway/service/session/SessionInformation.java b/gateway-service-session/src/main/java/org/apache/knox/gateway/service/session/SessionInformation.java index 638979e4b9..48c1ce798a 100644 --- a/gateway-service-session/src/main/java/org/apache/knox/gateway/service/session/SessionInformation.java +++ b/gateway-service-session/src/main/java/org/apache/knox/gateway/service/session/SessionInformation.java @@ -17,8 +17,8 @@ */ package org.apache.knox.gateway.service.session; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; +import jakarta.xml.bind.annotation.XmlElement; +import jakarta.xml.bind.annotation.XmlRootElement; @XmlRootElement(name = "sessioninfo") public class SessionInformation { diff --git a/gateway-service-session/src/main/java/org/apache/knox/gateway/service/session/SessionInformationMarshaller.java b/gateway-service-session/src/main/java/org/apache/knox/gateway/service/session/SessionInformationMarshaller.java index dde75c0faa..810ec069b7 100644 --- a/gateway-service-session/src/main/java/org/apache/knox/gateway/service/session/SessionInformationMarshaller.java +++ b/gateway-service-session/src/main/java/org/apache/knox/gateway/service/session/SessionInformationMarshaller.java @@ -30,8 +30,8 @@ import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.ext.MessageBodyWriter; import javax.ws.rs.ext.Provider; -import javax.xml.bind.JAXBException; -import javax.xml.bind.Marshaller; +import jakarta.xml.bind.JAXBException; +import jakarta.xml.bind.Marshaller; import org.eclipse.persistence.jaxb.JAXBContextFactory; import org.eclipse.persistence.jaxb.JAXBContextProperties; diff --git a/gateway-service-test/pom.xml b/gateway-service-test/pom.xml index 15d1e9ec1f..f99333efa4 100644 --- a/gateway-service-test/pom.xml +++ b/gateway-service-test/pom.xml @@ -43,21 +43,22 @@ - javax.xml.bind - jaxb-api + jakarta.xml.bind + jakarta.xml.bind-api + org.eclipse.persistence - eclipselink + org.eclipse.persistence.moxy javax.json @@ -67,6 +68,14 @@ org.glassfish javax.json + + jakarta.json + jakarta.json-api + + + org.eclipse.parsson + parsson + org.apache.commons diff --git a/gateway-service-test/src/main/java/org/apache/knox/gateway/service/test/ServiceTestResource.java b/gateway-service-test/src/main/java/org/apache/knox/gateway/service/test/ServiceTestResource.java index a1812a0e93..5a84f6c617 100644 --- a/gateway-service-test/src/main/java/org/apache/knox/gateway/service/test/ServiceTestResource.java +++ b/gateway-service-test/src/main/java/org/apache/knox/gateway/service/test/ServiceTestResource.java @@ -36,11 +36,11 @@ import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.core.Context; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlElementWrapper; -import javax.xml.bind.annotation.XmlRootElement; +import jakarta.xml.bind.annotation.XmlAccessType; +import jakarta.xml.bind.annotation.XmlAccessorType; +import jakarta.xml.bind.annotation.XmlElement; +import jakarta.xml.bind.annotation.XmlElementWrapper; +import jakarta.xml.bind.annotation.XmlRootElement; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; diff --git a/gateway-service-test/src/main/java/org/apache/knox/gateway/service/test/ServiceTestWrapperMarshaller.java b/gateway-service-test/src/main/java/org/apache/knox/gateway/service/test/ServiceTestWrapperMarshaller.java index 53d19b90a3..1b9ceee4d0 100644 --- a/gateway-service-test/src/main/java/org/apache/knox/gateway/service/test/ServiceTestWrapperMarshaller.java +++ b/gateway-service-test/src/main/java/org/apache/knox/gateway/service/test/ServiceTestWrapperMarshaller.java @@ -28,9 +28,9 @@ import javax.ws.rs.ext.MessageBodyWriter; import javax.ws.rs.ext.Provider; import javax.ws.rs.ext.Providers; -import javax.xml.bind.JAXBContext; -import javax.xml.bind.JAXBException; -import javax.xml.bind.Marshaller; +import jakarta.xml.bind.JAXBContext; +import jakarta.xml.bind.JAXBException; +import jakarta.xml.bind.Marshaller; import java.io.IOException; import java.io.OutputStream; import java.lang.annotation.Annotation; @@ -69,4 +69,4 @@ public void writeTo(ServiceTestResource.ServiceTestWrapper instance, Class ty throw new IOException(e); } } -} \ No newline at end of file +} diff --git a/gateway-service-webhdfs/pom.xml b/gateway-service-webhdfs/pom.xml index 388627e348..5f6a9f4256 100644 --- a/gateway-service-webhdfs/pom.xml +++ b/gateway-service-webhdfs/pom.xml @@ -68,6 +68,11 @@ javax.servlet javax.servlet-api + + org.apache.knox + gateway-util-common + test + org.apache.knox diff --git a/gateway-shell-release/pom.xml b/gateway-shell-release/pom.xml index 3d26cc8db7..e8b872b011 100644 --- a/gateway-shell-release/pom.xml +++ b/gateway-shell-release/pom.xml @@ -47,6 +47,27 @@ org.apache.knox.gateway.launcher.Launcher + + + + *:* + + schema/** + **/*.ldif + + + + *:* + + + META-INF/*.SF + META-INF/*.DSA + META-INF/*.RSA + META-INF/*.EC + META-INF/*.sig + + + diff --git a/gateway-shell/pom.xml b/gateway-shell/pom.xml index d38744e7c0..dca30f8020 100644 --- a/gateway-shell/pom.xml +++ b/gateway-shell/pom.xml @@ -53,6 +53,12 @@ org.codehaus.groovy groovy-groovysh + + + jline + jline + + org.codehaus.groovy @@ -67,7 +73,7 @@ jansi - jline + org.jline jline diff --git a/gateway-shell/src/main/java/org/apache/knox/gateway/shell/jdbc/derby/DerbyDatabase.java b/gateway-shell/src/main/java/org/apache/knox/gateway/shell/jdbc/derby/DerbyDatabase.java index 88405b64cd..aad51ae3ee 100644 --- a/gateway-shell/src/main/java/org/apache/knox/gateway/shell/jdbc/derby/DerbyDatabase.java +++ b/gateway-shell/src/main/java/org/apache/knox/gateway/shell/jdbc/derby/DerbyDatabase.java @@ -17,6 +17,7 @@ */ package org.apache.knox.gateway.shell.jdbc.derby; +import java.lang.reflect.InvocationTargetException; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; @@ -112,12 +113,12 @@ public boolean hasTable(String schemaName, String tableName) throws SQLException private void loadDriver(boolean networkServer) throws DerbyDatabaseException { final String driverToLoad = networkServer ? NETWORK_SERVER_DRIVER : EMBEDDED_DRIVER; try { - Class.forName(driverToLoad).newInstance(); + Class.forName(driverToLoad).getDeclaredConstructor().newInstance(); } catch (ClassNotFoundException e) { throw new DerbyDatabaseException("Unable to load the JDBC driver " + driverToLoad + ". Check your CLASSPATH.", e); } catch (InstantiationException e) { throw new DerbyDatabaseException("Unable to instantiate the JDBC driver " + driverToLoad, e); - } catch (IllegalAccessException e) { + } catch (IllegalAccessException | NoSuchMethodException | InvocationTargetException e) { throw new DerbyDatabaseException("Not allowed to access the JDBC driver " + driverToLoad, e); } } diff --git a/gateway-shell/src/main/java/org/apache/knox/gateway/shell/table/JDBCKnoxShellTableBuilder.java b/gateway-shell/src/main/java/org/apache/knox/gateway/shell/table/JDBCKnoxShellTableBuilder.java index 3d1e69ff9b..61b8064a0d 100644 --- a/gateway-shell/src/main/java/org/apache/knox/gateway/shell/table/JDBCKnoxShellTableBuilder.java +++ b/gateway-shell/src/main/java/org/apache/knox/gateway/shell/table/JDBCKnoxShellTableBuilder.java @@ -77,7 +77,7 @@ public JDBCKnoxShellTableBuilder driver(String driver) throws Exception { private void loadDriver() throws Exception { try { - Class.forName(driver).newInstance(); + Class.forName(driver).getDeclaredConstructor().newInstance(); } catch (ClassNotFoundException e) { System.out.println(String.format(Locale.US, "Unable to load the JDBC driver %s. Check your CLASSPATH.", driver)); throw e; @@ -143,4 +143,4 @@ public KnoxShellTable resultSet(ResultSet resultSet) throws SQLException { processResultSet(resultSet); return this.table; } -} \ No newline at end of file +} diff --git a/gateway-spi/pom.xml b/gateway-spi/pom.xml index 41df0a535a..853e9342c4 100644 --- a/gateway-spi/pom.xml +++ b/gateway-spi/pom.xml @@ -156,13 +156,17 @@ metrics-httpclient + + com.sun.activation + jakarta.activation + jakarta.activation jakarta.activation-api - javax.xml.bind - jaxb-api + jakarta.xml.bind + jakarta.xml.bind-api diff --git a/gateway-spi/src/main/java/org/apache/knox/gateway/dispatch/GatewayDispatchFilter.java b/gateway-spi/src/main/java/org/apache/knox/gateway/dispatch/GatewayDispatchFilter.java index 48196d1379..26952e547b 100644 --- a/gateway-spi/src/main/java/org/apache/knox/gateway/dispatch/GatewayDispatchFilter.java +++ b/gateway-spi/src/main/java/org/apache/knox/gateway/dispatch/GatewayDispatchFilter.java @@ -225,7 +225,7 @@ private T newInstanceFromName(String dispatchImpl, FilterConfig filterConfig if(constructor != null) { return (T) constructor.newInstance(filterConfig); } - return clazz.newInstance(); + return clazz.getDeclaredConstructor().newInstance(); } catch ( Exception e ) { throw new ServletException(e); } diff --git a/gateway-spi/src/main/java/org/apache/knox/gateway/filter/GatewayRequest.java b/gateway-spi/src/main/java/org/apache/knox/gateway/filter/GatewayRequest.java index 087589192c..089ce67bc9 100644 --- a/gateway-spi/src/main/java/org/apache/knox/gateway/filter/GatewayRequest.java +++ b/gateway-spi/src/main/java/org/apache/knox/gateway/filter/GatewayRequest.java @@ -17,7 +17,7 @@ */ package org.apache.knox.gateway.filter; -import javax.activation.MimeType; +import jakarta.activation.MimeType; import javax.servlet.http.HttpServletRequest; public interface GatewayRequest extends HttpServletRequest { diff --git a/gateway-spi/src/main/java/org/apache/knox/gateway/filter/GatewayRequestWrapper.java b/gateway-spi/src/main/java/org/apache/knox/gateway/filter/GatewayRequestWrapper.java index 851fe29a0c..09bd581815 100644 --- a/gateway-spi/src/main/java/org/apache/knox/gateway/filter/GatewayRequestWrapper.java +++ b/gateway-spi/src/main/java/org/apache/knox/gateway/filter/GatewayRequestWrapper.java @@ -19,7 +19,7 @@ import org.apache.knox.gateway.util.MimeTypes; -import javax.activation.MimeType; +import jakarta.activation.MimeType; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; diff --git a/gateway-spi/src/main/java/org/apache/knox/gateway/filter/GatewayResponse.java b/gateway-spi/src/main/java/org/apache/knox/gateway/filter/GatewayResponse.java index eff7e069e7..5b9fcc28b9 100644 --- a/gateway-spi/src/main/java/org/apache/knox/gateway/filter/GatewayResponse.java +++ b/gateway-spi/src/main/java/org/apache/knox/gateway/filter/GatewayResponse.java @@ -17,7 +17,7 @@ */ package org.apache.knox.gateway.filter; -import javax.activation.MimeType; +import jakarta.activation.MimeType; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.InputStream; diff --git a/gateway-spi/src/main/java/org/apache/knox/gateway/filter/GatewayResponseWrapper.java b/gateway-spi/src/main/java/org/apache/knox/gateway/filter/GatewayResponseWrapper.java index 25f5a310e4..b84e4dfeb6 100644 --- a/gateway-spi/src/main/java/org/apache/knox/gateway/filter/GatewayResponseWrapper.java +++ b/gateway-spi/src/main/java/org/apache/knox/gateway/filter/GatewayResponseWrapper.java @@ -20,7 +20,7 @@ import org.apache.commons.io.IOUtils; import org.apache.knox.gateway.util.MimeTypes; -import javax.activation.MimeType; +import jakarta.activation.MimeType; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponseWrapper; import java.io.IOException; diff --git a/gateway-spi/src/main/java/org/apache/knox/gateway/security/SubjectUtils.java b/gateway-spi/src/main/java/org/apache/knox/gateway/security/SubjectUtils.java index 5e354dd4c4..89adc15555 100644 --- a/gateway-spi/src/main/java/org/apache/knox/gateway/security/SubjectUtils.java +++ b/gateway-spi/src/main/java/org/apache/knox/gateway/security/SubjectUtils.java @@ -17,6 +17,8 @@ */ package org.apache.knox.gateway.security; +import de.thetaphi.forbiddenapis.SuppressForbidden; + import javax.security.auth.Subject; import java.security.AccessController; @@ -30,6 +32,11 @@ */ public class SubjectUtils { + /* + * There is no option in JDK 17 other then suppressing. + * For JDK 18+ use Subject.current() instead. + */ + @SuppressForbidden public static Subject getCurrentSubject() { return Subject.getSubject( AccessController.getContext() ); } diff --git a/gateway-spi/src/main/java/org/apache/knox/gateway/service/definition/ServiceDefinitionPair.java b/gateway-spi/src/main/java/org/apache/knox/gateway/service/definition/ServiceDefinitionPair.java index 856fd5a1ca..ae7d74b446 100644 --- a/gateway-spi/src/main/java/org/apache/knox/gateway/service/definition/ServiceDefinitionPair.java +++ b/gateway-spi/src/main/java/org/apache/knox/gateway/service/definition/ServiceDefinitionPair.java @@ -17,11 +17,11 @@ */ package org.apache.knox.gateway.service.definition; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; +import jakarta.xml.bind.annotation.XmlAccessType; +import jakarta.xml.bind.annotation.XmlAccessorType; +import jakarta.xml.bind.annotation.XmlElement; +import jakarta.xml.bind.annotation.XmlRootElement; +import jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter; import org.apache.knox.gateway.filter.rewrite.api.UrlRewriteRulesDescriptor; diff --git a/gateway-spi/src/main/java/org/apache/knox/gateway/service/definition/UrlRewriteRulesDescriptorAdapter.java b/gateway-spi/src/main/java/org/apache/knox/gateway/service/definition/UrlRewriteRulesDescriptorAdapter.java index a4ba66bda3..f6c942ec99 100644 --- a/gateway-spi/src/main/java/org/apache/knox/gateway/service/definition/UrlRewriteRulesDescriptorAdapter.java +++ b/gateway-spi/src/main/java/org/apache/knox/gateway/service/definition/UrlRewriteRulesDescriptorAdapter.java @@ -26,7 +26,7 @@ import java.nio.charset.StandardCharsets; import javax.xml.XMLConstants; -import javax.xml.bind.annotation.adapters.XmlAdapter; +import jakarta.xml.bind.annotation.adapters.XmlAdapter; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; diff --git a/gateway-spi/src/main/java/org/apache/knox/gateway/services/security/impl/ConfigurableEncryptor.java b/gateway-spi/src/main/java/org/apache/knox/gateway/services/security/impl/ConfigurableEncryptor.java index f7e869113e..563dfcb404 100644 --- a/gateway-spi/src/main/java/org/apache/knox/gateway/services/security/impl/ConfigurableEncryptor.java +++ b/gateway-spi/src/main/java/org/apache/knox/gateway/services/security/impl/ConfigurableEncryptor.java @@ -103,8 +103,7 @@ public EncryptionResult encrypt(String encrypt) throws Exception { public EncryptionResult encrypt(byte[] plain) throws Exception { byte[] salt = new byte[saltSize]; - SecureRandom rnd = new SecureRandom(); - rnd.nextBytes(salt); + SecureRandom.getInstanceStrong().nextBytes(salt); SecretKey tmp = getKeyFromPassword(new String(passPhrase), salt); SecretKey secret = new SecretKeySpec(tmp.getEncoded(), alg); diff --git a/gateway-spi/src/main/java/org/apache/knox/gateway/util/GroupBasedImpersonationProvider.java b/gateway-spi/src/main/java/org/apache/knox/gateway/util/GroupBasedImpersonationProvider.java new file mode 100644 index 0000000000..01d4df192f --- /dev/null +++ b/gateway-spi/src/main/java/org/apache/knox/gateway/util/GroupBasedImpersonationProvider.java @@ -0,0 +1,264 @@ +/* + * 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.knox.gateway.util; + +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.security.UserGroupInformation; +import org.apache.hadoop.security.authorize.AccessControlList; +import org.apache.hadoop.security.authorize.AuthorizationException; +import org.apache.hadoop.security.authorize.DefaultImpersonationProvider; +import org.apache.hadoop.util.MachineList; +import org.apache.knox.gateway.i18n.GatewaySpiMessages; +import org.apache.knox.gateway.i18n.messages.MessagesFactory; + +import java.net.InetAddress; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +import static org.apache.knox.gateway.util.AuthFilterUtils.PROXYGROUP_PREFIX; +import static org.apache.knox.gateway.util.AuthFilterUtils.PROXYUSER_PREFIX; + +/** + * An extension of Hadoop's DefaultImpersonationProvider that adds support for group-based impersonation. + * This provider allows users who belong to specific groups to impersonate other users. + */ +public class GroupBasedImpersonationProvider extends DefaultImpersonationProvider { + private static final GatewaySpiMessages LOG = MessagesFactory.get(GatewaySpiMessages.class); + private static final String CONF_HOSTS = ".hosts"; + private static final String CONF_USERS = ".users"; + private static final String CONF_GROUPS = ".groups"; + private static final String PREFIX_REGEX_EXP = "\\."; + private static final String USERS_GROUPS_REGEX_EXP = "[\\S]*(" + + Pattern.quote(CONF_USERS) + "|" + Pattern.quote(CONF_GROUPS) + ")"; + private static final String HOSTS_REGEX_EXP = "[\\S]*" + Pattern.quote(CONF_HOSTS); + private final Map proxyGroupsAcls = new HashMap<>(); + private Map groupProxyHosts = new HashMap<>(); + private String groupConfigPrefix; + private boolean doesProxyUserConfigExist = true; + static final String IMPERSONATION_ENABLED_PARAM = "impersonation.enabled"; + + public GroupBasedImpersonationProvider() { + super(); + } + + @Override + public Configuration getConf() { + return super.getConf(); + } + + @Override + public void setConf(Configuration conf) { + super.setConf(conf); + } + + @Override + public void init(String configurationPrefix) { + super.init(configurationPrefix); + + /* Check if user proxy configs are provided */ + final Map filteredProps = Optional.ofNullable(getConf().getPropsWithPrefix(PROXYUSER_PREFIX + ".")) + .orElse(Collections.emptyMap()) // handle null map defensively + .entrySet() + .stream() + .filter(entry -> !IMPERSONATION_ENABLED_PARAM.equals(entry.getKey())) // avoid NPE by reversing equals + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); + + doesProxyUserConfigExist = !filteredProps.isEmpty(); + + initGroupBasedProvider(PROXYGROUP_PREFIX); + } + + private void initGroupBasedProvider(final String proxyGroupPrefix) { + groupConfigPrefix = proxyGroupPrefix + + (proxyGroupPrefix.endsWith(".") ? "" : "."); + + String prefixRegEx = groupConfigPrefix.replace(".", PREFIX_REGEX_EXP); + String usersGroupsRegEx = prefixRegEx + USERS_GROUPS_REGEX_EXP; + String hostsRegEx = prefixRegEx + HOSTS_REGEX_EXP; + + // get list of users and groups per proxygroup + // Map of + Map allMatchKeys = + getConf().getValByRegex(usersGroupsRegEx); + + for (Map.Entry entry : allMatchKeys.entrySet()) { + //aclKey = hadoop.proxygroup.[VIRTUAL_GROUP] + String aclKey = getAclKey(entry.getKey()); + + if (!proxyGroupsAcls.containsKey(aclKey)) { + proxyGroupsAcls.put(aclKey, new AccessControlList( + allMatchKeys.get(aclKey + CONF_USERS), + allMatchKeys.get(aclKey + CONF_GROUPS))); + } + } + + // get hosts per proxygroup + allMatchKeys = getConf().getValByRegex(hostsRegEx); + for (Map.Entry entry : allMatchKeys.entrySet()) { + groupProxyHosts.put(entry.getKey(), + new MachineList(entry.getValue())); + } + } + + private String getAclKey(String key) { + int endIndex = key.lastIndexOf('.'); + if (endIndex != -1) { + return key.substring(0, endIndex); + } + return key; + } + + /** + * Authorization based on user and group impersonation policies. + * + * @param user the user information attempting the operation, which includes the real + * user and the effective impersonated user. + * @param remoteAddress the remote address from which the user is connecting. + * @throws AuthorizationException if the user is not authorized based on the + * configured impersonation and group policies. + */ + @Override + public void authorize(UserGroupInformation user, InetAddress remoteAddress) throws AuthorizationException { + authorize(user, remoteAddress, Collections.emptyList()); + } + + /** + * Authorization based on groups that are provided as a function argument + * + * @param user the user information attempting the operation, which includes the real + * user and the effective impersonated user. + * @param groups the list of groups to check for authorization. + * @param remoteAddress the remote address from which the user is connecting. + * @throws AuthorizationException if the user is not authorized based on the + * configured impersonation and group policies. + */ + public void authorize(UserGroupInformation user, InetAddress remoteAddress, List groups) throws AuthorizationException { + + /** + * check for proxy user authorization only if PROXYUSER_PREFIX properties exist. + * If proxy is configured then use those properties instead of group-based properties + * given user based configs are more finegrained. + */ + if (doesProxyUserConfigExist) { + try{ + /* check for proxy user authorization */ + super.authorize(user, remoteAddress); + } catch (final AuthorizationException e) { + /* + * Log and try group based impersonation. + * Since this provider is for groups no need to check if + * proxy group config exists, we know it does. + */ + LOG.failedToImpersonateUserTryingGroups(user.getUserName(), e.toString()); + } + } + /* check for proxy group authorization */ + checkProxyGroupAuthorization(user, remoteAddress, groups); + } + + + /** + * Helper method to check if the group a given user belongs to is authorized to impersonate + * Returns true if the user is authorized, false otherwise. + * + * @param user + * @param remoteAddress + * @return + */ + private void checkProxyGroupAuthorization(final UserGroupInformation user, final InetAddress remoteAddress, List groups) throws AuthorizationException { + if (user == null) { + throw new IllegalArgumentException("user is null."); + } + + final UserGroupInformation realUser = user.getRealUser(); + if (realUser == null) { + return; + } + + // Get the real user's groups (both real and virtual) + Set realUserGroups = new HashSet<>(); + /* Add provided groups */ + if(groups != null && !groups.isEmpty()) { + realUserGroups.addAll(groups); + } + /* Add groups from subject */ + if (user.getRealUser().getGroupNames() != null) { + Collections.addAll(realUserGroups, user.getRealUser().getGroupNames()); + } + + boolean proxyGroupFound = false; + // Check if any of the real user's groups have permission to impersonate the proxy user + proxyGroupFound = isProxyGroupFound(user, realUserGroups, proxyGroupFound); + + if (!proxyGroupFound) { + LOG.failedToImpersonateGroups(realUser.getUserName(), realUserGroups.toString(), user.getUserName()); + throw new AuthorizationException("User: " + realUser.getUserName() + + " with groups " + realUserGroups.toString() + + " is not allowed to impersonate " + user.getUserName()); + } + + boolean proxyGroupHostFound = false; + proxyGroupHostFound = isProxyGroupHostFound(remoteAddress, realUserGroups, proxyGroupHostFound); + + if (!proxyGroupHostFound) { + LOG.failedToImpersonateGroupsFromAddress(realUser.getUserName(), realUserGroups.toString(), user.getUserName(), remoteAddress.toString()); + throw new AuthorizationException("User: " + realUser.getUserName() + + " with groups " + realUserGroups.toString() + + " from address " + remoteAddress.toString() + + " is not allowed to impersonate " + user.getUserName()); + } + + /* all checks pass */ + } + + private boolean isProxyGroupHostFound(InetAddress remoteAddress, Set realUserGroups, boolean proxyGroupHostFound) { + for (final String group : realUserGroups) { + final MachineList machineList = groupProxyHosts.get(groupConfigPrefix + group + CONF_HOSTS); + + if (machineList == null || !machineList.includes(remoteAddress)) { + continue; + } else { + proxyGroupHostFound = true; + break; + } + } + return proxyGroupHostFound; + } + + private boolean isProxyGroupFound(UserGroupInformation user, Set realUserGroups, boolean proxyGroupFound) { + for (String group : realUserGroups) { + final AccessControlList acl = proxyGroupsAcls.get(groupConfigPrefix + + group); + + if (acl == null || !acl.isUserAllowed(user)) { + continue; + } else { + proxyGroupFound = true; + break; + } + } + return proxyGroupFound; + } + +} diff --git a/gateway-test-release-utils/pom.xml b/gateway-test-release-utils/pom.xml index 5fae357a95..d951391caf 100644 --- a/gateway-test-release-utils/pom.xml +++ b/gateway-test-release-utils/pom.xml @@ -115,4 +115,43 @@ mina-core + + + + org.apache.maven.plugins + maven-shade-plugin + + + package + shade + + false + false + + + + *:* + + schema/** + **/*.ldif + + + + + *:* + + META-INF/*.SF + META-INF/*.DSA + META-INF/*.RSA + META-INF/*.EC + META-INF/*.sig + + + + + + + + + diff --git a/gateway-test-release/webhdfs-kerb-test/pom.xml b/gateway-test-release/webhdfs-kerb-test/pom.xml index a389fe235e..0645728738 100644 --- a/gateway-test-release/webhdfs-kerb-test/pom.xml +++ b/gateway-test-release/webhdfs-kerb-test/pom.xml @@ -32,15 +32,18 @@ - com.sun.jersey + org.glassfish.jersey.core jersey-server - ${hadoop-jersey.version} test - com.sun.jersey - jersey-servlet - ${hadoop-jersey.version} + org.glassfish.jersey.containers + jersey-container-servlet-core + test + + + org.glassfish.jersey.containers + jersey-container-servlet test diff --git a/gateway-test-release/webhdfs-test/pom.xml b/gateway-test-release/webhdfs-test/pom.xml index 7972143bb2..ce084fdd97 100644 --- a/gateway-test-release/webhdfs-test/pom.xml +++ b/gateway-test-release/webhdfs-test/pom.xml @@ -33,15 +33,18 @@ - com.sun.jersey + org.glassfish.jersey.core jersey-server - ${hadoop-jersey.version} test - com.sun.jersey - jersey-servlet - ${hadoop-jersey.version} + org.glassfish.jersey.containers + jersey-container-servlet-core + test + + + org.glassfish.jersey.containers + jersey-container-servlet test diff --git a/gateway-test-release/webhdfs-test/src/test/java/org/apache/hadoop/http/HttpServer2.java b/gateway-test-release/webhdfs-test/src/test/java/org/apache/hadoop/http/HttpServer2.java deleted file mode 100644 index a14bfd05e5..0000000000 --- a/gateway-test-release/webhdfs-test/src/test/java/org/apache/hadoop/http/HttpServer2.java +++ /dev/null @@ -1,1706 +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.hadoop.http; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InterruptedIOException; -import java.io.PrintStream; -import java.net.BindException; -import java.net.InetSocketAddress; -import java.net.MalformedURLException; -import java.net.URI; -import java.net.URL; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Properties; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletRequestWrapper; -import javax.servlet.http.HttpServletResponse; - -import com.google.common.base.Preconditions; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Lists; -import com.sun.jersey.spi.container.servlet.ServletContainer; -import de.thetaphi.forbiddenapis.SuppressForbidden; -import org.apache.hadoop.HadoopIllegalArgumentException; -import org.apache.hadoop.classification.InterfaceAudience; -import org.apache.hadoop.classification.InterfaceStability; -import org.apache.hadoop.conf.ConfServlet; -import org.apache.hadoop.conf.Configuration; -import org.apache.hadoop.conf.Configuration.IntegerRanges; -import org.apache.hadoop.fs.CommonConfigurationKeys; -import org.apache.hadoop.jmx.JMXJsonServlet; -import org.apache.hadoop.log.LogLevel; -import org.apache.hadoop.security.AuthenticationFilterInitializer; -import org.apache.hadoop.security.SecurityUtil; -import org.apache.hadoop.security.UserGroupInformation; -import org.apache.hadoop.security.authentication.server.AuthenticationFilter; -import org.apache.hadoop.security.authentication.util.SignerSecretProvider; -import org.apache.hadoop.security.authorize.AccessControlList; -import org.apache.hadoop.security.ssl.SSLFactory; -import org.apache.hadoop.util.ReflectionUtils; -import org.apache.hadoop.util.Shell; -import org.apache.hadoop.util.StringUtils; -import org.eclipse.jetty.http.HttpVersion; -import org.eclipse.jetty.server.ConnectionFactory; -import org.eclipse.jetty.server.Connector; -import org.eclipse.jetty.server.Handler; -import org.eclipse.jetty.server.HttpConfiguration; -import org.eclipse.jetty.server.HttpConnectionFactory; -import org.eclipse.jetty.server.RequestLog; -import org.eclipse.jetty.server.SecureRequestCustomizer; -import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.server.ServerConnector; -import org.eclipse.jetty.server.SslConnectionFactory; -import org.eclipse.jetty.server.handler.ContextHandlerCollection; -import org.eclipse.jetty.server.handler.HandlerCollection; -import org.eclipse.jetty.server.handler.RequestLogHandler; -import org.eclipse.jetty.server.session.SessionHandler; -import org.eclipse.jetty.servlet.DefaultServlet; -import org.eclipse.jetty.servlet.FilterHolder; -import org.eclipse.jetty.servlet.FilterMapping; -import org.eclipse.jetty.servlet.ServletContextHandler; -import org.eclipse.jetty.servlet.ServletHandler; -import org.eclipse.jetty.servlet.ServletHolder; -import org.eclipse.jetty.servlet.ServletMapping; -import org.eclipse.jetty.util.ArrayUtil; -import org.eclipse.jetty.util.MultiException; -import org.eclipse.jetty.util.ssl.SslContextFactory; -import org.eclipse.jetty.util.thread.QueuedThreadPool; -import org.eclipse.jetty.webapp.WebAppContext; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Create a Jetty embedded server to answer http requests. The primary goal is - * to serve up status information for the server. There are three contexts: - * "/logs/" points to the log directory "/static/" points to common static - * files (src/webapps/static) "/" the jsp server code from - * (src/webapps/NAME) - * - * This class is a fork of the old HttpServer. HttpServer exists for - * compatibility reasons. See HBASE-10336 for more details. - */ -@InterfaceAudience.Private -@InterfaceStability.Evolving -public final class HttpServer2 implements FilterContainer { - public static final Logger LOG = LoggerFactory.getLogger(HttpServer2.class); - - public static final String HTTP_SCHEME = "http"; - public static final String HTTPS_SCHEME = "https"; - - public static final String HTTP_MAX_REQUEST_HEADER_SIZE_KEY = - "hadoop.http.max.request.header.size"; - public static final int HTTP_MAX_REQUEST_HEADER_SIZE_DEFAULT = 65536; - public static final String HTTP_MAX_RESPONSE_HEADER_SIZE_KEY = - "hadoop.http.max.response.header.size"; - public static final int HTTP_MAX_RESPONSE_HEADER_SIZE_DEFAULT = 65536; - - public static final String HTTP_SOCKET_BACKLOG_SIZE_KEY = - "hadoop.http.socket.backlog.size"; - public static final int HTTP_SOCKET_BACKLOG_SIZE_DEFAULT = 128; - public static final String HTTP_MAX_THREADS_KEY = "hadoop.http.max.threads"; - public static final String HTTP_ACCEPTOR_COUNT_KEY = - "hadoop.http.acceptor.count"; - // -1 to use default behavior of setting count based on CPU core count - public static final int HTTP_ACCEPTOR_COUNT_DEFAULT = -1; - public static final String HTTP_SELECTOR_COUNT_KEY = - "hadoop.http.selector.count"; - // -1 to use default behavior of setting count based on CPU core count - public static final int HTTP_SELECTOR_COUNT_DEFAULT = -1; - // idle timeout in milliseconds - public static final String HTTP_IDLE_TIMEOUT_MS_KEY = - "hadoop.http.idle_timeout.ms"; - public static final int HTTP_IDLE_TIMEOUT_MS_DEFAULT = 10000; - public static final String HTTP_TEMP_DIR_KEY = "hadoop.http.temp.dir"; - - public static final String FILTER_INITIALIZER_PROPERTY - = "hadoop.http.filter.initializers"; - - // The ServletContext attribute where the daemon Configuration - // gets stored. - public static final String CONF_CONTEXT_ATTRIBUTE = "hadoop.conf"; - public static final String ADMINS_ACL = "admins.acl"; - public static final String SPNEGO_FILTER = "SpnegoFilter"; - public static final String NO_CACHE_FILTER = "NoCacheFilter"; - - public static final String BIND_ADDRESS = "bind.address"; - - private final AccessControlList adminsAcl; - - private final Server webServer; - - private final HandlerCollection handlers; - - private final List listeners = Lists.newArrayList(); - - private final WebAppContext webAppContext; - private final boolean findPort; - private final IntegerRanges portRanges; - private final Map defaultContexts = - new HashMap<>(); - private final List filterNames = new ArrayList<>(); - static final String STATE_DESCRIPTION_ALIVE = " - alive"; - static final String STATE_DESCRIPTION_NOT_LIVE = " - not live"; - private final SignerSecretProvider secretProvider; - private XFrameOption xFrameOption; - private boolean xFrameOptionIsEnabled; - public static final String HTTP_HEADER_PREFIX = "hadoop.http.header."; - private static final String HTTP_HEADER_REGEX = - "hadoop\\.http\\.header\\.([a-zA-Z\\-_]+)"; - static final String X_XSS_PROTECTION = - "X-XSS-Protection:1; mode=block"; - static final String X_CONTENT_TYPE_OPTIONS = - "X-Content-Type-Options:nosniff"; - private static final String X_FRAME_OPTIONS = "X-FRAME-OPTIONS"; - private static final Pattern PATTERN_HTTP_HEADER_REGEX = - Pattern.compile(HTTP_HEADER_REGEX); - /** - * Class to construct instances of HTTP server with specific options. - */ - public static class Builder { - private List endpoints = Lists.newArrayList(); - private String name; - private Configuration conf; - private Configuration sslConf; - private String[] pathSpecs; - private AccessControlList adminsAcl; - private boolean securityEnabled; - private String usernameConfKey; - private String keytabConfKey; - private boolean needsClientAuth; - private String trustStore; - private String trustStorePassword; - private String trustStoreType; - - private String keyStore; - private String keyStorePassword; - private String keyStoreType; - - // The -keypass option in keytool - private String keyPassword; - - private boolean findPort; - private IntegerRanges portRanges; - - private String hostName; - private boolean disallowFallbackToRandomSignerSecretProvider; - private String authFilterConfigurationPrefix = "hadoop.http.authentication."; - private String excludeCiphers; - - private boolean xFrameEnabled; - private XFrameOption xFrameOption = XFrameOption.SAMEORIGIN; - - public Builder setName(String name){ - this.name = name; - return this; - } - - /* - * Add an endpoint that the HTTP server should listen to. - * - * @param endpoint - * the endpoint of that the HTTP server should listen to. The - * scheme specifies the protocol (i.e. HTTP / HTTPS), the host - * specifies the binding address, and the port specifies the - * listening port. Unspecified or zero port means that the server - * can listen to any port. - */ - public Builder addEndpoint(URI endpoint) { - endpoints.add(endpoint); - return this; - } - - /* - * Set the hostname of the http server. The host name is used to resolve the - * _HOST field in Kerberos principals. The hostname of the first listener - * will be used if the name is unspecified. - */ - public Builder hostName(String hostName) { - this.hostName = hostName; - return this; - } - - public Builder trustStore(String location, String password, String type) { - this.trustStore = location; - this.trustStorePassword = password; - this.trustStoreType = type; - return this; - } - - public Builder keyStore(String location, String password, String type) { - this.keyStore = location; - this.keyStorePassword = password; - this.keyStoreType = type; - return this; - } - - public Builder keyPassword(String password) { - this.keyPassword = password; - return this; - } - - /* - * Specify whether the server should authorize the client in SSL - * connections. - */ - public Builder needsClientAuth(boolean value) { - this.needsClientAuth = value; - return this; - } - - public Builder setFindPort(boolean findPort) { - this.findPort = findPort; - return this; - } - - public Builder setPortRanges(IntegerRanges ranges) { - this.portRanges = ranges; - return this; - } - - public Builder setConf(Configuration conf) { - this.conf = conf; - return this; - } - - /* - * Specify the SSL configuration to load. This API provides an alternative - * to keyStore/keyPassword/trustStore. - */ - public Builder setSSLConf(Configuration sslCnf) { - this.sslConf = sslCnf; - return this; - } - - public Builder setPathSpec(String[] pathSpec) { - this.pathSpecs = pathSpec; - return this; - } - - public Builder setACL(AccessControlList acl) { - this.adminsAcl = acl; - return this; - } - - public Builder setSecurityEnabled(boolean securityEnabled) { - this.securityEnabled = securityEnabled; - return this; - } - - public Builder setUsernameConfKey(String usernameConfKey) { - this.usernameConfKey = usernameConfKey; - return this; - } - - public Builder setKeytabConfKey(String keytabConfKey) { - this.keytabConfKey = keytabConfKey; - return this; - } - - public Builder disallowFallbackToRandomSingerSecretProvider(boolean value) { - this.disallowFallbackToRandomSignerSecretProvider = value; - return this; - } - - public Builder authFilterConfigurationPrefix(String value) { - this.authFilterConfigurationPrefix = value; - return this; - } - - public Builder excludeCiphers(String pExcludeCiphers) { - this.excludeCiphers = pExcludeCiphers; - return this; - } - - /** - * Adds the ability to control X_FRAME_OPTIONS on HttpServer2. - * @param xFrameEnabled - True enables X_FRAME_OPTIONS false disables it. - * @return Builder. - */ - public Builder configureXFrame(boolean xFrameEnabled) { - this.xFrameEnabled = xFrameEnabled; - return this; - } - - /** - * Sets a valid X-Frame-option that can be used by HttpServer2. - * @param option - String DENY, SAMEORIGIN or ALLOW-FROM are the only valid - * options. Any other value will throw IllegalArgument - * Exception. - * @return Builder. - */ - public Builder setXFrameOption(String option) { - this.xFrameOption = XFrameOption.getEnum(option); - return this; - } - - /** - * A wrapper of {@link Configuration#getPassword(String)}. It returns - * String instead of char[]. - * - * @param conf the configuration - * @param name the property name - * @return the password string or null - */ - private static String getPasswordString(Configuration conf, String name) - throws IOException { - char[] passchars = conf.getPassword(name); - if (passchars == null) { - return null; - } - return new String(passchars); - } - - /** - * Load SSL properties from the SSL configuration. - */ - @SuppressForbidden - private void loadSSLConfiguration() throws IOException { - if (sslConf == null) { - return; - } - needsClientAuth = sslConf.getBoolean( - SSLFactory.SSL_SERVER_NEED_CLIENT_AUTH, - SSLFactory.SSL_SERVER_NEED_CLIENT_AUTH_DEFAULT); - keyStore = sslConf.getTrimmed(SSLFactory.SSL_SERVER_KEYSTORE_LOCATION); - if (keyStore == null || keyStore.isEmpty()) { - throw new IOException(String.format("Property %s not specified", - SSLFactory.SSL_SERVER_KEYSTORE_LOCATION)); - } - keyStorePassword = getPasswordString(sslConf, - SSLFactory.SSL_SERVER_KEYSTORE_PASSWORD); - if (keyStorePassword == null) { - throw new IOException(String.format("Property %s not specified", - SSLFactory.SSL_SERVER_KEYSTORE_PASSWORD)); - } - keyStoreType = sslConf.get(SSLFactory.SSL_SERVER_KEYSTORE_TYPE, - SSLFactory.SSL_SERVER_KEYSTORE_TYPE_DEFAULT); - keyPassword = getPasswordString(sslConf, - SSLFactory.SSL_SERVER_KEYSTORE_KEYPASSWORD); - trustStore = sslConf.get(SSLFactory.SSL_SERVER_TRUSTSTORE_LOCATION); - trustStorePassword = getPasswordString(sslConf, - SSLFactory.SSL_SERVER_TRUSTSTORE_PASSWORD); - trustStoreType = sslConf.get(SSLFactory.SSL_SERVER_TRUSTSTORE_TYPE, - SSLFactory.SSL_SERVER_TRUSTSTORE_TYPE_DEFAULT); - excludeCiphers = sslConf.get(SSLFactory.SSL_SERVER_EXCLUDE_CIPHER_LIST); - } - - public HttpServer2 build() throws IOException { - Preconditions.checkNotNull(name, "name is not set"); - Preconditions.checkState(!endpoints.isEmpty(), "No endpoints specified"); - - if (hostName == null) { - hostName = endpoints.get(0).getHost(); - } - - if (this.conf == null) { - conf = new Configuration(); - } - - HttpServer2 server = new HttpServer2(this); // NOPMD - - if (this.securityEnabled) { - server.initSpnego(conf, hostName, usernameConfKey, keytabConfKey); - } - - for (URI ep : endpoints) { - if (HTTPS_SCHEME.equals(ep.getScheme())) { - loadSSLConfiguration(); - break; - } - } - - int requestHeaderSize = conf.getInt( - HTTP_MAX_REQUEST_HEADER_SIZE_KEY, - HTTP_MAX_REQUEST_HEADER_SIZE_DEFAULT); - int responseHeaderSize = conf.getInt( - HTTP_MAX_RESPONSE_HEADER_SIZE_KEY, - HTTP_MAX_RESPONSE_HEADER_SIZE_DEFAULT); - int idleTimeout = conf.getInt(HTTP_IDLE_TIMEOUT_MS_KEY, - HTTP_IDLE_TIMEOUT_MS_DEFAULT); - - HttpConfiguration httpConfig = new HttpConfiguration(); - httpConfig.setRequestHeaderSize(requestHeaderSize); - httpConfig.setResponseHeaderSize(responseHeaderSize); - httpConfig.setSendServerVersion(false); - - int backlogSize = conf.getInt(HTTP_SOCKET_BACKLOG_SIZE_KEY, - HTTP_SOCKET_BACKLOG_SIZE_DEFAULT); - - for (URI ep : endpoints) { - final ServerConnector connector; - String scheme = ep.getScheme(); - if (HTTP_SCHEME.equals(scheme)) { - connector = createHttpChannelConnector(server.webServer, - httpConfig); - } else if (HTTPS_SCHEME.equals(scheme)) { - connector = createHttpsChannelConnector(server.webServer, - httpConfig); - } else { - throw new HadoopIllegalArgumentException( - "unknown scheme for endpoint:" + ep); - } - connector.setHost(ep.getHost()); - connector.setPort(ep.getPort() == -1 ? 0 : ep.getPort()); - connector.setAcceptQueueSize(backlogSize); - connector.setIdleTimeout(idleTimeout); - server.addListener(connector); - } - server.loadListeners(); - return server; - } - - private ServerConnector createHttpChannelConnector( - Server server, HttpConfiguration httpConfig) { - ServerConnector conn = new ServerConnector(server, - conf.getInt(HTTP_ACCEPTOR_COUNT_KEY, HTTP_ACCEPTOR_COUNT_DEFAULT), - conf.getInt(HTTP_SELECTOR_COUNT_KEY, HTTP_SELECTOR_COUNT_DEFAULT)); - ConnectionFactory connFactory = new HttpConnectionFactory(httpConfig); - conn.addConnectionFactory(connFactory); - if(Shell.WINDOWS) { - // result of setting the SO_REUSEADDR flag is different on Windows - // http://msdn.microsoft.com/en-us/library/ms740621(v=vs.85).aspx - // without this 2 NN's can start on the same machine and listen on - // the same port with indeterminate routing of incoming requests to them - conn.setReuseAddress(false); - } - return conn; - } - - private ServerConnector createHttpsChannelConnector( - Server server, HttpConfiguration httpConfig) { - httpConfig.setSecureScheme(HTTPS_SCHEME); - httpConfig.addCustomizer(new SecureRequestCustomizer()); - ServerConnector conn = createHttpChannelConnector(server, httpConfig); - - SslContextFactory.Server sslContextFactory = new SslContextFactory.Server(); - sslContextFactory.setNeedClientAuth(needsClientAuth); - sslContextFactory.setKeyManagerPassword(keyPassword); - if (keyStore != null) { - sslContextFactory.setKeyStorePath(keyStore); - sslContextFactory.setKeyStoreType(keyStoreType); - sslContextFactory.setKeyStorePassword(keyStorePassword); - } - if (trustStore != null) { - sslContextFactory.setTrustStorePath(trustStore); - sslContextFactory.setTrustStoreType(trustStoreType); - sslContextFactory.setTrustStorePassword(trustStorePassword); - } - if(null != excludeCiphers && !excludeCiphers.isEmpty()) { - sslContextFactory.setExcludeCipherSuites( - StringUtils.getTrimmedStrings(excludeCiphers)); - LOG.info("Excluded Cipher List:" + excludeCiphers); - } - - conn.addFirstConnectionFactory(new SslConnectionFactory(sslContextFactory, - HttpVersion.HTTP_1_1.asString())); - - return conn; - } - } - - private HttpServer2(final Builder b) throws IOException { - final String appDir = getWebAppsPath(b.name); - this.webServer = new Server(); - this.adminsAcl = b.adminsAcl; - this.handlers = new HandlerCollection(); - this.webAppContext = createWebAppContext(b, adminsAcl, appDir); - this.xFrameOptionIsEnabled = b.xFrameEnabled; - this.xFrameOption = b.xFrameOption; - - try { - this.secretProvider = - constructSecretProvider(b, webAppContext.getServletContext()); - this.webAppContext.getServletContext().setAttribute - (AuthenticationFilter.SIGNER_SECRET_PROVIDER_ATTRIBUTE, - secretProvider); - } catch(IOException e) { - throw e; - } catch (Exception e) { - throw new IOException(e); - } - - this.findPort = b.findPort; - this.portRanges = b.portRanges; - initializeWebServer(b.name, b.hostName, b.conf, b.pathSpecs); - } - - private void initializeWebServer(String name, String hostName, - Configuration conf, String[] pathSpecs) - throws IOException { - - Preconditions.checkNotNull(webAppContext); - - int maxThreads = conf.getInt(HTTP_MAX_THREADS_KEY, -1); - // If HTTP_MAX_THREADS is not configured, QueueThreadPool() will use the - // default value (currently 250). - - QueuedThreadPool threadPool = (QueuedThreadPool) webServer.getThreadPool(); - threadPool.setDaemon(true); - if (maxThreads != -1) { - // Minimum number of threads must be > 3. - // DatanodeHttpServer sets the HTTP_MAX_THREADS_KEY to 3 - threadPool.setMaxThreads(Math.max(maxThreads, 4)); - } - - SessionHandler sessionHandler = webAppContext.getSessionHandler(); - sessionHandler.setHttpOnly(true); - sessionHandler.getSessionCookieConfig().setSecure(true); - - ContextHandlerCollection contexts = new ContextHandlerCollection(); - RequestLog requestLog = HttpRequestLog.getRequestLog(name); - - handlers.addHandler(contexts); - if (requestLog != null) { - RequestLogHandler requestLogHandler = new RequestLogHandler(); - requestLogHandler.setRequestLog(requestLog); - handlers.addHandler(requestLogHandler); - } - handlers.addHandler(webAppContext); - final String appDir = getWebAppsPath(name); - addDefaultApps(contexts, appDir, conf); - webServer.setHandler(handlers); - - Map xFrameParams = setHeaders(conf); - addGlobalFilter("safety", QuotingInputFilter.class.getName(), xFrameParams); - final FilterInitializer[] initializers = getFilterInitializers(conf); - if (initializers != null) { - conf = new Configuration(conf); - conf.set(BIND_ADDRESS, hostName); - for (FilterInitializer c : initializers) { - c.initFilter(this, conf); - } - } - - addDefaultServlets(); - - if (pathSpecs != null) { - for (String path : pathSpecs) { - LOG.info("adding path spec: " + path); - addFilterPathMapping(path, webAppContext); - } - } - } - - private void addListener(ServerConnector connector) { - listeners.add(connector); - } - - private static WebAppContext createWebAppContext(Builder b, - AccessControlList adminsAcl, final String appDir) { - WebAppContext ctx = new WebAppContext(); - ctx.setDefaultsDescriptor(null); - ServletHolder holder = new ServletHolder(new DefaultServlet()); - Map params = ImmutableMap. builder() - .put("acceptRanges", "true") - .put("dirAllowed", "false") - .put("gzip", "true") - .put("useFileMappedBuffer", "true") - .build(); - holder.setInitParameters(params); - ctx.setWelcomeFiles(new String[] {"index.html"}); - ctx.addServlet(holder, "/"); - ctx.setDisplayName(b.name); - ctx.setContextPath("/"); - ctx.setWar(appDir + "/" + b.name); - String tempDirectory = b.conf.get(HTTP_TEMP_DIR_KEY); - if (tempDirectory != null && !tempDirectory.isEmpty()) { - ctx.setTempDirectory(new File(tempDirectory)); - ctx.setAttribute("javax.servlet.context.tempdir", tempDirectory); - } - ctx.getServletContext().setAttribute(CONF_CONTEXT_ATTRIBUTE, b.conf); - ctx.getServletContext().setAttribute(ADMINS_ACL, adminsAcl); - addNoCacheFilter(ctx); - return ctx; - } - - private static SignerSecretProvider constructSecretProvider(final Builder b, - ServletContext ctx) - throws Exception { - final Configuration conf = b.conf; - Properties config = getFilterProperties(conf, - b.authFilterConfigurationPrefix); - return AuthenticationFilter.constructSecretProvider( - ctx, config, b.disallowFallbackToRandomSignerSecretProvider); - } - - private static Properties getFilterProperties(Configuration conf, String - prefix) { - Properties prop = new Properties(); - Map filterConfig = AuthenticationFilterInitializer - .getFilterConfigMap(conf, prefix); - prop.putAll(filterConfig); - return prop; - } - - private static void addNoCacheFilter(ServletContextHandler ctxt) { - defineFilter(ctxt, NO_CACHE_FILTER, NoCacheFilter.class.getName(), - Collections. emptyMap(), new String[] { "/*" }); - } - - /** Get an array of FilterConfiguration specified in the conf */ - private static FilterInitializer[] getFilterInitializers(Configuration conf) { - if (conf == null) { - return null; - } - - Class[] classes = conf.getClasses(FILTER_INITIALIZER_PROPERTY); - if (classes == null) { - return null; - } - - FilterInitializer[] initializers = new FilterInitializer[classes.length]; - for(int i = 0; i < classes.length; i++) { - initializers[i] = (FilterInitializer)ReflectionUtils.newInstance( - classes[i], conf); - } - return initializers; - } - - /* - * Add default apps. - * @param appDir The application directory - */ - protected void addDefaultApps(ContextHandlerCollection parent, - final String appDir, Configuration conf) { - // set up the context for "/logs/" if "hadoop.log.dir" property is defined - // and it's enabled. - String logDir = System.getProperty("hadoop.log.dir"); - boolean logsEnabled = conf.getBoolean( - CommonConfigurationKeys.HADOOP_HTTP_LOGS_ENABLED, - CommonConfigurationKeys.HADOOP_HTTP_LOGS_ENABLED_DEFAULT); - if (logDir != null && logsEnabled) { - ServletContextHandler logContext = - new ServletContextHandler(parent, "/logs"); - logContext.setResourceBase(logDir); - logContext.addServlet(AdminAuthorizedServlet.class, "/*"); - if (conf.getBoolean( - CommonConfigurationKeys.HADOOP_JETTY_LOGS_SERVE_ALIASES, - CommonConfigurationKeys.DEFAULT_HADOOP_JETTY_LOGS_SERVE_ALIASES)) { - @SuppressWarnings("unchecked") - Map params = logContext.getInitParams(); - params.put("org.eclipse.jetty.servlet.Default.aliases", "true"); - } - logContext.setDisplayName("logs"); - SessionHandler handler = new SessionHandler(); - handler.setHttpOnly(true); - handler.getSessionCookieConfig().setSecure(true); - logContext.setSessionHandler(handler); - setContextAttributes(logContext, conf); - addNoCacheFilter(logContext); - defaultContexts.put(logContext, true); - } - // set up the context for "/static/*" - ServletContextHandler staticContext = - new ServletContextHandler(parent, "/static"); - staticContext.setResourceBase(appDir + "/static"); - staticContext.addServlet(DefaultServlet.class, "/*"); - staticContext.setDisplayName("static"); - @SuppressWarnings("unchecked") - Map params = staticContext.getInitParams(); - params.put("org.eclipse.jetty.servlet.Default.dirAllowed", "false"); - params.put("org.eclipse.jetty.servlet.Default.gzip", "true"); - SessionHandler handler = new SessionHandler(); - handler.setHttpOnly(true); - handler.getSessionCookieConfig().setSecure(true); - staticContext.setSessionHandler(handler); - setContextAttributes(staticContext, conf); - defaultContexts.put(staticContext, true); - } - - private void setContextAttributes(ServletContextHandler context, - Configuration conf) { - context.getServletContext().setAttribute(CONF_CONTEXT_ATTRIBUTE, conf); - context.getServletContext().setAttribute(ADMINS_ACL, adminsAcl); - } - - /** - * Add default servlets. - */ - protected void addDefaultServlets() { - // set up default servlets - addServlet("stacks", "/stacks", StackServlet.class); - addServlet("logLevel", "/logLevel", LogLevel.Servlet.class); - addServlet("jmx", "/jmx", JMXJsonServlet.class); - addServlet("conf", "/conf", ConfServlet.class); - } - - public void addContext(ServletContextHandler ctxt, boolean isFiltered) { - handlers.addHandler(ctxt); - addNoCacheFilter(ctxt); - defaultContexts.put(ctxt, isFiltered); - } - - /** - * Set a value in the webapp context. These values are available to the jsp - * pages as "application.getAttribute(name)". - * @param name The name of the attribute - * @param value The value of the attribute - */ - public void setAttribute(String name, Object value) { - webAppContext.setAttribute(name, value); - } - - /** - * Add a Jersey resource package. - * @param packageName The Java package name containing the Jersey resource. - * @param pathSpec The path spec for the servlet - */ - public void addJerseyResourcePackage(final String packageName, - final String pathSpec) { - addJerseyResourcePackage(packageName, pathSpec, Collections.emptyMap()); - } - - /** - * Add a Jersey resource package. - * @param packageName The Java package name containing the Jersey resource. - * @param pathSpec The path spec for the servlet - * @param params properties and features for ResourceConfig - */ - public void addJerseyResourcePackage(final String packageName, - final String pathSpec, Map params) { - LOG.info("addJerseyResourcePackage: packageName=" + packageName - + ", pathSpec=" + pathSpec); - final ServletHolder sh = new ServletHolder(ServletContainer.class); - sh.setInitParameter("com.sun.jersey.config.property.resourceConfigClass", - "com.sun.jersey.api.core.PackagesResourceConfig"); - sh.setInitParameter("com.sun.jersey.config.property.packages", packageName); - for (Map.Entry entry : params.entrySet()) { - sh.setInitParameter(entry.getKey(), entry.getValue()); - } - webAppContext.addServlet(sh, pathSpec); - } - - /** - * Add a servlet in the server. - * @param name The name of the servlet (can be passed as null) - * @param pathSpec The path spec for the servlet - * @param clazz The servlet class - */ - public void addServlet(String name, String pathSpec, - Class clazz) { - addInternalServlet(name, pathSpec, clazz, false); - addFilterPathMapping(pathSpec, webAppContext); - } - - /** - * Add an internal servlet in the server. - * Note: This method is to be used for adding servlets that facilitate - * internal communication and not for user facing functionality. For - * servlets added using this method, filters are not enabled. - * - * @param name The name of the servlet (can be passed as null) - * @param pathSpec The path spec for the servlet - * @param clazz The servlet class - */ - public void addInternalServlet(String name, String pathSpec, - Class clazz) { - addInternalServlet(name, pathSpec, clazz, false); - } - - /** - * Add an internal servlet in the server, specifying whether or not to - * protect with Kerberos authentication. - * Note: This method is to be used for adding servlets that facilitate - * internal communication and not for user facing functionality. For - * servlets added using this method, filters (except internal Kerberos - * filters) are not enabled. - * - * @param name The name of the servlet (can be passed as null) - * @param pathSpec The path spec for the servlet - * @param clazz The servlet class - * @param requireAuth Require Kerberos authenticate to access servlet - */ - public void addInternalServlet(String name, String pathSpec, - Class clazz, boolean requireAuth) { - ServletHolder holder = new ServletHolder(clazz); - if (name != null) { - holder.setName(name); - } - // Jetty doesn't like the same path spec mapping to different servlets, so - // if there's already a mapping for this pathSpec, remove it and assume that - // the newest one is the one we want - final ServletMapping[] servletMappings = - webAppContext.getServletHandler().getServletMappings(); - for (ServletMapping servletMapping : servletMappings) { - if (servletMapping.containsPathSpec(pathSpec)) { - if (LOG.isDebugEnabled()) { - LOG.debug("Found existing " + servletMapping.getServletName() + - " servlet at path " + pathSpec + "; will replace mapping" + - " with " + holder.getName() + " servlet"); - } - ServletMapping[] newServletMappings = - ArrayUtil.removeFromArray(servletMappings, servletMapping); - webAppContext.getServletHandler() - .setServletMappings(newServletMappings); - break; - } - } - webAppContext.addServlet(holder, pathSpec); - - if(requireAuth && UserGroupInformation.isSecurityEnabled()) { - LOG.info("Adding Kerberos (SPNEGO) filter to " + name); - ServletHandler handler = webAppContext.getServletHandler(); - FilterMapping fmap = new FilterMapping(); - fmap.setPathSpec(pathSpec); - fmap.setFilterName(SPNEGO_FILTER); - fmap.setDispatches(FilterMapping.ALL); - handler.addFilterMapping(fmap); - } - } - - /** - * Add an internal servlet in the server, with initialization parameters. - * Note: This method is to be used for adding servlets that facilitate - * internal communication and not for user facing functionality. For - * servlets added using this method, filters (except internal Kerberos - * filters) are not enabled. - * - * @param name The name of the servlet (can be passed as null) - * @param pathSpec The path spec for the servlet - * @param clazz The servlet class - * @param params init parameters - */ - public void addInternalServlet(String name, String pathSpec, - Class clazz, Map params) { - // Jetty doesn't like the same path spec mapping to different servlets, so - // if there's already a mapping for this pathSpec, remove it and assume that - // the newest one is the one we want - final ServletHolder sh = new ServletHolder(clazz); - sh.setName(name); - sh.setInitParameters(params); - final ServletMapping[] servletMappings = - webAppContext.getServletHandler().getServletMappings(); - for (ServletMapping servletMapping : servletMappings) { - if (servletMapping.containsPathSpec(pathSpec)) { - if (LOG.isDebugEnabled()) { - LOG.debug("Found existing " + servletMapping.getServletName() + - " servlet at path " + pathSpec + "; will replace mapping" + - " with " + sh.getName() + " servlet"); - } - ServletMapping[] newServletMappings = - ArrayUtil.removeFromArray(servletMappings, servletMapping); - webAppContext.getServletHandler() - .setServletMappings(newServletMappings); - break; - } - } - webAppContext.addServlet(sh, pathSpec); - } - - /** - * Add the given handler to the front of the list of handlers. - * - * @param handler The handler to add - */ - public void addHandlerAtFront(Handler handler) { - Handler[] h = ArrayUtil.prependToArray( - handler, this.handlers.getHandlers(), Handler.class); - handlers.setHandlers(h); - } - - /** - * Add the given handler to the end of the list of handlers. - * - * @param handler The handler to add - */ - public void addHandlerAtEnd(Handler handler) { - handlers.addHandler(handler); - } - - @Override - public void addFilter(String name, String classname, - Map parameters) { - - FilterHolder filterHolder = getFilterHolder(name, classname, parameters); - final String[] USER_FACING_URLS = { "*.html", "*.jsp" }; - FilterMapping fmap = getFilterMapping(name, USER_FACING_URLS); - defineFilter(webAppContext, filterHolder, fmap); - LOG.info( - "Added filter " + name + " (class=" + classname + ") to context " - + webAppContext.getDisplayName()); - final String[] ALL_URLS = { "/*" }; - fmap = getFilterMapping(name, ALL_URLS); - for (Map.Entry e - : defaultContexts.entrySet()) { - if (e.getValue()) { - ServletContextHandler ctx = e.getKey(); - defineFilter(ctx, filterHolder, fmap); - LOG.info("Added filter " + name + " (class=" + classname - + ") to context " + ctx.getDisplayName()); - } - } - filterNames.add(name); - } - - @Override - public void addGlobalFilter(String name, String classname, - Map parameters) { - final String[] ALL_URLS = { "/*" }; - FilterHolder filterHolder = getFilterHolder(name, classname, parameters); - FilterMapping fmap = getFilterMapping(name, ALL_URLS); - defineFilter(webAppContext, filterHolder, fmap); - for (ServletContextHandler ctx : defaultContexts.keySet()) { - defineFilter(ctx, filterHolder, fmap); - } - LOG.info("Added global filter '" + name + "' (class=" + classname + ")"); - } - - /* - * Define a filter for a context and set up default url mappings. - */ - public static void defineFilter(ServletContextHandler ctx, String name, - String classname, Map parameters, String[] urls) { - FilterHolder filterHolder = getFilterHolder(name, classname, parameters); - FilterMapping fmap = getFilterMapping(name, urls); - defineFilter(ctx, filterHolder, fmap); - } - - /* - * Define a filter for a context and set up default url mappings. - */ - private static void defineFilter(ServletContextHandler ctx, - FilterHolder holder, FilterMapping fmap) { - ServletHandler handler = ctx.getServletHandler(); - handler.addFilter(holder, fmap); - } - - private static FilterMapping getFilterMapping(String name, String[] urls) { - FilterMapping fmap = new FilterMapping(); - fmap.setPathSpecs(urls); - fmap.setDispatches(FilterMapping.ALL); - fmap.setFilterName(name); - return fmap; - } - - private static FilterHolder getFilterHolder(String name, String classname, - Map parameters) { - FilterHolder holder = new FilterHolder(); - holder.setName(name); - holder.setClassName(classname); - if (parameters != null) { - holder.setInitParameters(parameters); - } - return holder; - } - - /** - * Add the path spec to the filter path mapping. - * @param pathSpec The path spec - * @param webAppCtx The WebApplicationContext to add to - */ - protected void addFilterPathMapping(String pathSpec, - ServletContextHandler webAppCtx) { - ServletHandler handler = webAppCtx.getServletHandler(); - for(String name : filterNames) { - FilterMapping fmap = new FilterMapping(); - fmap.setPathSpec(pathSpec); - fmap.setFilterName(name); - fmap.setDispatches(FilterMapping.ALL); - handler.addFilterMapping(fmap); - } - } - - /** - * Get the value in the webapp context. - * @param name The name of the attribute - * @return The value of the attribute - */ - public Object getAttribute(String name) { - return webAppContext.getAttribute(name); - } - - public WebAppContext getWebAppContext(){ - return this.webAppContext; - } - - /** - * Get the pathname to the webapps files. - * @param appName eg "secondary" or "datanode" - * @return the pathname as a URL - * @throws FileNotFoundException if 'webapps' directory cannot be found - * on CLASSPATH or in the development location. - */ - protected String getWebAppsPath(String appName) throws FileNotFoundException { - URL resourceUrl = null; - File webResourceDevLocation = new File("src/main/webapps", appName); - if (webResourceDevLocation.exists()) { - LOG.info("Web server is in development mode. Resources " - + "will be read from the source tree."); - try { - resourceUrl = webResourceDevLocation.getParentFile().toURI().toURL(); - } catch (MalformedURLException e) { - throw new FileNotFoundException("Mailformed URL while finding the " - + "web resource dir:" + e.getMessage()); - } - } else { - resourceUrl = - getClass().getClassLoader().getResource("webapps/" + appName); - - if (resourceUrl == null) { - throw new FileNotFoundException("webapps/" + appName + - " not found in CLASSPATH"); - } - } - String urlString = resourceUrl.toString(); - return urlString.substring(0, urlString.lastIndexOf('/')); - } - - /** - * Get the port that the server is on - * @return the port - */ - @Deprecated - public int getPort() { - return ((ServerConnector)webServer.getConnectors()[0]).getLocalPort(); - } - - /** - * Get the address that corresponds to a particular connector. - * - * @param index index of the connector - * @return the corresponding address for the connector, or null if there's no - * such connector or the connector is not bounded or was closed. - */ - public InetSocketAddress getConnectorAddress(int index) { - Preconditions.checkArgument(index >= 0); - if (index > webServer.getConnectors().length) { - return null; - } - - ServerConnector c = (ServerConnector)webServer.getConnectors()[index]; - if (c.getLocalPort() == -1 || c.getLocalPort() == -2) { - // The connector is not bounded or was closed - return null; - } - - return new InetSocketAddress(c.getHost(), c.getLocalPort()); - } - - /* - * Set the min, max number of worker threads (simultaneous connections). - */ - public void setThreads(int min, int max) { - QueuedThreadPool pool = (QueuedThreadPool) webServer.getThreadPool(); - pool.setMinThreads(min); - pool.setMaxThreads(max); - } - - private void initSpnego(Configuration conf, String hostName, - String usernameConfKey, String keytabConfKey) throws IOException { - Map params = new HashMap<>(); - String principalInConf = conf.get(usernameConfKey); - if (principalInConf != null && !principalInConf.isEmpty()) { - params.put("kerberos.principal", SecurityUtil.getServerPrincipal( - principalInConf, hostName)); - } - String httpKeytab = conf.get(keytabConfKey); - if (httpKeytab != null && !httpKeytab.isEmpty()) { - params.put("kerberos.keytab", httpKeytab); - } - params.put(AuthenticationFilter.AUTH_TYPE, "kerberos"); - defineFilter(webAppContext, SPNEGO_FILTER, - AuthenticationFilter.class.getName(), params, null); - } - - /* - * Start the server. Does not wait for the server to start. - */ - public void start() throws IOException { - try { - try { - openListeners(); - webServer.start(); - } catch (IOException ex) { - LOG.info("HttpServer.start() threw a non Bind IOException", ex); - throw ex; - } catch (MultiException ex) { - LOG.info("HttpServer.start() threw a MultiException", ex); - throw ex; - } - // Make sure there is no handler failures. - Handler[] hs = webServer.getHandlers(); - for (Handler handler : hs) { - if (handler.isFailed()) { - throw new IOException( - "Problem in starting http server. Server handlers failed"); - } - } - // Make sure there are no errors initializing the context. - Throwable unavailableException = webAppContext.getUnavailableException(); - if (unavailableException != null) { - // Have to stop the webserver, or else its non-daemon threads - // will hang forever. - webServer.stop(); - throw new IOException("Unable to initialize WebAppContext", - unavailableException); - } - } catch (IOException e) { - throw e; - } catch (InterruptedException e) { - throw (IOException) new InterruptedIOException( - "Interrupted while starting HTTP server").initCause(e); - } catch (Exception e) { - throw new IOException("Problem starting http server", e); - } - } - - private void loadListeners() { - for (Connector c : listeners) { - webServer.addConnector(c); - } - } - - /** - * Bind listener by closing and opening the listener. - * @param listener listener to bind - * @throws Exception Exception on opening listener - */ - private static void bindListener(ServerConnector listener) throws Exception { - // jetty has a bug where you can't reopen a listener that previously - // failed to open w/o issuing a close first, even if the port is changed - listener.close(); - listener.open(); - LOG.info("Jetty bound to port " + listener.getLocalPort()); - } - - /** - * Create bind exception by wrapping the bind exception thrown. - * @param listener listener to check - * @param ex exception to check - * @return returns the exception - */ - private static BindException constructBindException(ServerConnector listener, - BindException ex) { - BindException be = new BindException("Port in use: " - + listener.getHost() + ":" + listener.getPort()); - if (ex != null) { - be.initCause(ex); - } - return be; - } - - /** - * Bind using single configured port. If findPort is true, we will try to bind - * after incrementing port till a free port is found. - * @param listener jetty listener. - * @param port port which is set in the listener. - * @throws Exception exception on binding - */ - private void bindForSinglePort(ServerConnector listener, int port) - throws Exception { - while (true) { - try { - bindListener(listener); - break; - } catch (BindException ex) { - if (port == 0 || !findPort) { - throw constructBindException(listener, ex); - } - } - // try the next port number - listener.setPort(++port); - Thread.sleep(100); - } - } - - /** - * Bind using port ranges. Keep on looking for a free port in the port range - * and throw a bind exception if no port in the configured range binds. - * @param listener jetty listener. - * @param startPort initial port which is set in the listener. - * @throws Exception exception on binding - */ - private void bindForPortRange(ServerConnector listener, int startPort) - throws Exception { - BindException bindException = null; - try { - bindListener(listener); - return; - } catch (BindException ex) { - // Ignore exception. - bindException = ex; - } - for(Integer port : portRanges) { - if (port == startPort) { - continue; - } - Thread.sleep(100); - listener.setPort(port); - try { - bindListener(listener); - return; - } catch (BindException ex) { - // Ignore exception. Move to next port. - bindException = ex; - } - } - throw constructBindException(listener, bindException); - } - - /** - * Open the main listener for the server - * @throws Exception exception opening listener - */ - void openListeners() throws Exception { - LOG.debug("opening listeners: {}", listeners); - for (ServerConnector listener : listeners) { - if (listener.getLocalPort() != -1 && listener.getLocalPort() != -2) { - // This listener is either started externally or has been bound or was - // closed - continue; - } - int port = listener.getPort(); - if (portRanges != null && port != 0) { - bindForPortRange(listener, port); - } else { - bindForSinglePort(listener, port); - } - } - } - - /* - * stop the server - */ - public void stop() throws Exception { - MultiException exception = null; - for (ServerConnector c : listeners) { - try { - c.close(); - } catch (Exception e) { - LOG.error( - "Error while stopping listener for webapp" - + webAppContext.getDisplayName(), e); - exception = addMultiException(exception, e); - } - } - - try { - // explicitly destroy the secret provider - secretProvider.destroy(); - // clear & stop webAppContext attributes to avoid memory leaks. - webAppContext.clearAttributes(); - webAppContext.stop(); - } catch (Exception e) { - LOG.error("Error while stopping web app context for webapp " - + webAppContext.getDisplayName(), e); - exception = addMultiException(exception, e); - } - - try { - webServer.stop(); - } catch (Exception e) { - LOG.error("Error while stopping web server for webapp " - + webAppContext.getDisplayName(), e); - exception = addMultiException(exception, e); - } - - if (exception != null) { - exception.ifExceptionThrow(); - } - - } - - private MultiException addMultiException(MultiException exception, Exception e) { - if(exception == null){ - exception = new MultiException(); - } - exception.add(e); - return exception; - } - - public void join() throws InterruptedException { - webServer.join(); - } - - /** - * Test for the availability of the web server - * @return true if the web server is started, false otherwise - */ - public boolean isAlive() { - return webServer != null && webServer.isStarted(); - } - - @Override - public String toString() { - Preconditions.checkState(!listeners.isEmpty()); - StringBuilder sb = new StringBuilder("HttpServer (") - .append(isAlive() ? STATE_DESCRIPTION_ALIVE - : STATE_DESCRIPTION_NOT_LIVE) - .append("), listening at:"); - for (ServerConnector l : listeners) { - sb.append(l.getHost()).append(':').append(l.getPort()).append("/,"); - } - return sb.toString(); - } - - /** - * Checks the user has privileges to access to instrumentation servlets. - * - * If hadoop.security.instrumentation.requires.admin is set to FALSE - * (default value) it always returns TRUE. - * - * If hadoop.security.instrumentation.requires.admin is set to TRUE - * it will check that if the current user is in the admin ACLS. If the user is - * in the admin ACLs it returns TRUE, otherwise it returns FALSE. - * - * @param servletContext the servlet context. - * @param request the servlet request. - * @param response the servlet response. - * @return TRUE/FALSE based on the logic described above. - * @throws IOException exception on error - */ - public static boolean isInstrumentationAccessAllowed( - ServletContext servletContext, HttpServletRequest request, - HttpServletResponse response) throws IOException { - Configuration conf = - (Configuration) servletContext.getAttribute(CONF_CONTEXT_ATTRIBUTE); - - boolean access = true; - boolean adminAccess = conf.getBoolean( - CommonConfigurationKeys.HADOOP_SECURITY_INSTRUMENTATION_REQUIRES_ADMIN, - false); - if (adminAccess) { - access = hasAdministratorAccess(servletContext, request, response); - } - return access; - } - - /** - * Does the user sending the HttpServletRequest has the administrator ACLs? If - * it isn't the case, response will be modified to send an error to the user. - * - * @param servletContext the servlet context. - * @param request the servlet request. - * @param response used to send the error response if user does not have admin access. - * @return true if admin-authorized, false otherwise - * @throws IOException exception on error - */ - public static boolean hasAdministratorAccess( - ServletContext servletContext, HttpServletRequest request, - HttpServletResponse response) throws IOException { - Configuration conf = - (Configuration) servletContext.getAttribute(CONF_CONTEXT_ATTRIBUTE); - // If there is no authorization, anybody has administrator access. - if (!conf.getBoolean( - CommonConfigurationKeys.HADOOP_SECURITY_AUTHORIZATION, false)) { - return true; - } - - String remoteUser = request.getRemoteUser(); - if (remoteUser == null) { - response.sendError(HttpServletResponse.SC_FORBIDDEN, - "Unauthenticated users are not " + - "authorized to access this page."); - return false; - } - - if (servletContext.getAttribute(ADMINS_ACL) != null && - !userHasAdministratorAccess(servletContext, remoteUser)) { - response.sendError(HttpServletResponse.SC_FORBIDDEN, - "Unauthenticated users are not " + - "authorized to access this page."); - LOG.warn("User " + remoteUser + " is unauthorized to access the page " - + request.getRequestURI() + "."); - return false; - } - - return true; - } - - /** - * Get the admin ACLs from the given ServletContext and check if the given - * user is in the ACL. - * - * @param servletContext the context containing the admin ACL. - * @param remoteUser the remote user to check for. - * @return true if the user is present in the ACL, false if no ACL is set or - * the user is not present - */ - public static boolean userHasAdministratorAccess(ServletContext servletContext, - String remoteUser) { - AccessControlList adminsAcl = (AccessControlList) servletContext - .getAttribute(ADMINS_ACL); - UserGroupInformation remoteUserUGI = - UserGroupInformation.createRemoteUser(remoteUser); - return adminsAcl != null && adminsAcl.isUserAllowed(remoteUserUGI); - } - - /** - * A very simple servlet to serve up a text representation of the current - * stack traces. It both returns the stacks to the caller and logs them. - * Currently the stack traces are done sequentially rather than exactly the - * same data. - */ - public static class StackServlet extends HttpServlet { - private static final long serialVersionUID = -6284183679759467039L; - - @Override - public void doGet(HttpServletRequest request, HttpServletResponse response) - throws ServletException, IOException { - if (!HttpServer2.isInstrumentationAccessAllowed(getServletContext(), - request, response)) { - return; - } - response.setContentType("text/plain; charset=UTF-8"); - try (PrintStream out = new PrintStream( - response.getOutputStream(), false, "UTF-8")) { - ReflectionUtils.printThreadInfo(out, ""); - } - ReflectionUtils.logThreadInfo(LOG, "jsp requested", 1); - } - } - - /** - * A Servlet input filter that quotes all HTML active characters in the - * parameter names and values. The goal is to quote the characters to make - * all of the servlets resistant to cross-site scripting attacks. It also - * sets X-FRAME-OPTIONS in the header to mitigate clickjacking attacks. - */ - public static class QuotingInputFilter implements Filter { - - private FilterConfig config; - private Map headerMap; - - public static class RequestQuoter extends HttpServletRequestWrapper { - private final HttpServletRequest rawRequest; - - public RequestQuoter(HttpServletRequest rawRequest) { - super(rawRequest); - this.rawRequest = rawRequest; - } - - /** - * Return the set of parameter names, quoting each name. - */ - @Override - public Enumeration getParameterNames() { - return new Enumeration() { - private Enumeration rawIterator = rawRequest.getParameterNames(); - @Override - public boolean hasMoreElements() { - return rawIterator.hasMoreElements(); - } - - @Override - public String nextElement() { - return HtmlQuoting.quoteHtmlChars(rawIterator.nextElement()); - } - }; - } - - /** - * Unquote the name and quote the value. - */ - @Override - public String getParameter(String name) { - return HtmlQuoting.quoteHtmlChars(rawRequest.getParameter - (HtmlQuoting.unquoteHtmlChars(name))); - } - - @Override - public String[] getParameterValues(String name) { - String unquoteName = HtmlQuoting.unquoteHtmlChars(name); - String[] unquoteValue = rawRequest.getParameterValues(unquoteName); - if (unquoteValue == null) { - return null; - } - String[] result = new String[unquoteValue.length]; - for(int i=0; i < result.length; ++i) { - result[i] = HtmlQuoting.quoteHtmlChars(unquoteValue[i]); - } - return result; - } - - @SuppressWarnings("unchecked") - @Override - public Map getParameterMap() { - Map result = new HashMap<>(); - Map raw = rawRequest.getParameterMap(); - for (Map.Entry item: raw.entrySet()) { - String[] rawValue = item.getValue(); - String[] cookedValue = new String[rawValue.length]; - for(int i=0; i< rawValue.length; ++i) { - cookedValue[i] = HtmlQuoting.quoteHtmlChars(rawValue[i]); - } - result.put(HtmlQuoting.quoteHtmlChars(item.getKey()), cookedValue); - } - return result; - } - - /** - * Quote the url so that users specifying the HOST HTTP header - * can't inject attacks. - */ - @Override - public StringBuffer getRequestURL(){ - String url = rawRequest.getRequestURL().toString(); - return new StringBuffer(HtmlQuoting.quoteHtmlChars(url)); - } - - /** - * Quote the server name so that users specifying the HOST HTTP header - * can't inject attacks. - */ - @Override - public String getServerName() { - return HtmlQuoting.quoteHtmlChars(rawRequest.getServerName()); - } - } - - @Override - public void init(FilterConfig config) throws ServletException { - this.config = config; - initHttpHeaderMap(); - } - - @Override - public void destroy() { - } - - @Override - public void doFilter(ServletRequest request, - ServletResponse response, - FilterChain chain - ) throws IOException, ServletException { - HttpServletRequestWrapper quoted = - new RequestQuoter((HttpServletRequest) request); - HttpServletResponse httpResponse = (HttpServletResponse) response; - - String mime = inferMimeType(request); - if (mime == null) { - httpResponse.setContentType("text/plain; charset=utf-8"); - } else if (mime.startsWith("text/html")) { - // HTML with unspecified encoding, we want to - // force HTML with utf-8 encoding - // This is to avoid the following security issue: - // http://openmya.hacker.jp/hasegawa/security/utf7cs.html - httpResponse.setContentType("text/html; charset=utf-8"); - } else if (mime.startsWith("application/xml")) { - httpResponse.setContentType("text/xml; charset=utf-8"); - } - headerMap.forEach((k, v) -> httpResponse.addHeader(k, v)); - chain.doFilter(quoted, httpResponse); - } - - /** - * Infer the mime type for the response based on the extension of the request - * URI. Returns null if unknown. - */ - private String inferMimeType(ServletRequest request) { - String path = ((HttpServletRequest)request).getRequestURI(); - ServletContextHandler.Context sContext = - (ServletContextHandler.Context)config.getServletContext(); - String mime = sContext.getMimeType(path); - return (mime == null) ? null : mime; - } - - private void initHttpHeaderMap() { - Enumeration params = this.config.getInitParameterNames(); - headerMap = new HashMap<>(); - while (params.hasMoreElements()) { - String key = params.nextElement(); - Matcher m = PATTERN_HTTP_HEADER_REGEX.matcher(key); - if (m.matches()) { - String headerKey = m.group(1); - headerMap.put(headerKey, config.getInitParameter(key)); - } - } - } - } - /** - * The X-FRAME-OPTIONS header in HTTP response to mitigate clickjacking - * attack. - */ - public enum XFrameOption { - DENY("DENY"), SAMEORIGIN("SAMEORIGIN"), ALLOWFROM("ALLOW-FROM"); - - XFrameOption(String name) { - this.name = name; - } - - private final String name; - - @Override - public String toString() { - return this.name; - } - - /** - * We cannot use valueOf since the AllowFrom enum differs from its value - * Allow-From. This is a helper method that does exactly what valueof does, - * but allows us to handle the AllowFrom issue gracefully. - * - * @param value - String must be DENY, SAMEORIGIN or ALLOW-FROM. - * @return XFrameOption or throws IllegalException. - */ - private static XFrameOption getEnum(String value) { - Preconditions.checkState(value != null && !value.isEmpty()); - for (XFrameOption xoption : values()) { - if (value.equals(xoption.toString())) { - return xoption; - } - } - throw new IllegalArgumentException("Unexpected value in xFrameOption."); - } - } - - - private Map setHeaders(Configuration conf) { - Map xFrameParams = new HashMap<>(); - Map headerConfigMap = - conf.getValByRegex(HTTP_HEADER_REGEX); - - xFrameParams.putAll(getDefaultHeaders()); - if(this.xFrameOptionIsEnabled) { - xFrameParams.put(HTTP_HEADER_PREFIX+X_FRAME_OPTIONS, - this.xFrameOption.toString()); - } - xFrameParams.putAll(headerConfigMap); - return xFrameParams; - } - - private Map getDefaultHeaders() { - Map headers = new HashMap<>(); - String[] splitVal = X_CONTENT_TYPE_OPTIONS.split(":"); - headers.put(HTTP_HEADER_PREFIX + splitVal[0], - splitVal[1]); - splitVal = X_XSS_PROTECTION.split(":"); - headers.put(HTTP_HEADER_PREFIX + splitVal[0], - splitVal[1]); - return headers; - } -} diff --git a/gateway-test-utils/pom.xml b/gateway-test-utils/pom.xml index 8e673bb815..28539c1e9d 100644 --- a/gateway-test-utils/pom.xml +++ b/gateway-test-utils/pom.xml @@ -29,6 +29,11 @@ gateway-test-utils A collection of common utilities used for testing. + + 17 + 17 + + org.hamcrest diff --git a/gateway-test-utils/src/main/java/org/apache/knox/test/TestUtils.java b/gateway-test-utils/src/main/java/org/apache/knox/test/TestUtils.java index 6304c6c96a..31106bdf28 100644 --- a/gateway-test-utils/src/main/java/org/apache/knox/test/TestUtils.java +++ b/gateway-test-utils/src/main/java/org/apache/knox/test/TestUtils.java @@ -52,7 +52,7 @@ import java.util.concurrent.Callable; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; - +@SuppressWarnings("PMD") public class TestUtils { private static final Logger LOG = LogManager.getLogger(TestUtils.class); diff --git a/gateway-test-utils/src/main/java/org/apache/knox/test/mock/MockHttpServletRequest.java b/gateway-test-utils/src/main/java/org/apache/knox/test/mock/MockHttpServletRequest.java index a5f3f4f092..39d1352f15 100644 --- a/gateway-test-utils/src/main/java/org/apache/knox/test/mock/MockHttpServletRequest.java +++ b/gateway-test-utils/src/main/java/org/apache/knox/test/mock/MockHttpServletRequest.java @@ -39,7 +39,7 @@ import java.util.Enumeration; import java.util.Locale; import java.util.Map; - +@SuppressWarnings("PMD") public class MockHttpServletRequest implements HttpServletRequest { private String queryString; diff --git a/gateway-test-utils/src/main/java/org/apache/knox/test/mock/MockRequestMatcher.java b/gateway-test-utils/src/main/java/org/apache/knox/test/mock/MockRequestMatcher.java index f8f6915c69..e5f85b1390 100644 --- a/gateway-test-utils/src/main/java/org/apache/knox/test/mock/MockRequestMatcher.java +++ b/gateway-test-utils/src/main/java/org/apache/knox/test/mock/MockRequestMatcher.java @@ -49,7 +49,7 @@ import static org.xmlmatchers.XmlMatchers.isEquivalentTo; import static org.xmlmatchers.transform.XmlConverters.the; import static uk.co.datumedge.hamcrest.json.SameJSONAs.sameJSONAs; - +@SuppressWarnings("PMD") public class MockRequestMatcher { private String from; diff --git a/gateway-test-utils/src/main/java/org/apache/knox/test/mock/MockServletContext.java b/gateway-test-utils/src/main/java/org/apache/knox/test/mock/MockServletContext.java index 6ab98b20bc..1f8b216b42 100644 --- a/gateway-test-utils/src/main/java/org/apache/knox/test/mock/MockServletContext.java +++ b/gateway-test-utils/src/main/java/org/apache/knox/test/mock/MockServletContext.java @@ -34,7 +34,7 @@ import java.util.EventListener; import java.util.Map; import java.util.Set; - +@SuppressWarnings("PMD") public class MockServletContext implements ServletContext { @Override diff --git a/gateway-test/pom.xml b/gateway-test/pom.xml index b8cfe0fca8..e4fd1cc47c 100644 --- a/gateway-test/pom.xml +++ b/gateway-test/pom.xml @@ -177,11 +177,55 @@ io.rest-assured rest-assured test + + + org.apache.groovy + groovy + + + org.apache.groovy + groovy-xml + + + org.codehaus.groovy + groovy + + + org.codehaus.groovy + groovy-xml + + + org.codehaus.groovy + groovy-json + + io.rest-assured json-path test + + + org.apache.groovy + groovy + + + org.apache.groovy + groovy-xml + + + org.codehaus.groovy + groovy + + + org.codehaus.groovy + groovy-xml + + + org.codehaus.groovy + groovy-json + + @@ -212,6 +256,13 @@ test + + + org.glassfish.jersey.inject + jersey-hk2 + test + + com.mycila.xmltool xmltool @@ -295,6 +346,16 @@ log4j-core test + + jakarta.json + jakarta.json-api + test + + + org.eclipse.parsson + parsson + test + javax.ws.rs @@ -322,6 +383,11 @@ shrinkwrap-api test + + org.apache.hadoop + hadoop-common + test + diff --git a/gateway-test/src/test/java/org/apache/knox/gateway/GatewayAdminFuncTest.java b/gateway-test/src/test/java/org/apache/knox/gateway/GatewayAdminFuncTest.java index a21972a1d4..8695b78a65 100644 --- a/gateway-test/src/test/java/org/apache/knox/gateway/GatewayAdminFuncTest.java +++ b/gateway-test/src/test/java/org/apache/knox/gateway/GatewayAdminFuncTest.java @@ -147,7 +147,8 @@ private static XMLTag createTopology() { .gotoRoot(); } - @Test( timeout = TestUtils.MEDIUM_TIMEOUT ) + //@Test( timeout = TestUtils.MEDIUM_TIMEOUT ) + @Test public void testAdminService() throws ClassNotFoundException { TestUtils.LOG_ENTER(); diff --git a/gateway-test/src/test/java/org/apache/knox/gateway/GatewayAdminTopologyFuncTest.java b/gateway-test/src/test/java/org/apache/knox/gateway/GatewayAdminTopologyFuncTest.java index 2102eb8d5c..4928ed920b 100644 --- a/gateway-test/src/test/java/org/apache/knox/gateway/GatewayAdminTopologyFuncTest.java +++ b/gateway-test/src/test/java/org/apache/knox/gateway/GatewayAdminTopologyFuncTest.java @@ -349,10 +349,11 @@ public void testTopologyCollection() { .when().get(serviceUrl); given() - //.log().all() + .log().all() .auth().preemptive().basic(username, password) + .header("Accept", MediaType.APPLICATION_XML) .then() - //.log().all() + .log().all() .statusCode(HttpStatus.SC_OK) .contentType(MediaType.APPLICATION_XML) .when().get(serviceUrl); diff --git a/gateway-test/src/test/java/org/apache/knox/gateway/GatewayLocalServiceFuncTest.java b/gateway-test/src/test/java/org/apache/knox/gateway/GatewayLocalServiceFuncTest.java index 5643d5b5ea..1718d495a0 100644 --- a/gateway-test/src/test/java/org/apache/knox/gateway/GatewayLocalServiceFuncTest.java +++ b/gateway-test/src/test/java/org/apache/knox/gateway/GatewayLocalServiceFuncTest.java @@ -23,7 +23,6 @@ import org.apache.knox.gateway.config.GatewayConfig; import org.apache.knox.gateway.services.DefaultGatewayServices; import org.apache.knox.gateway.services.ServiceLifecycleException; -import org.apache.knox.test.TestUtils; import org.apache.http.HttpStatus; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -150,7 +149,7 @@ private static XMLTag createTopology() { .gotoRoot(); } - @Test( timeout = TestUtils.MEDIUM_TIMEOUT ) + @Test public void testJerseyService() throws ClassNotFoundException { LOG_ENTER(); assertThat( ClassLoader.getSystemClassLoader().loadClass( "org.glassfish.jersey.servlet.ServletContainer" ), notNullValue() ); diff --git a/gateway-test/src/test/java/org/apache/knox/gateway/GatewaySslFuncTest.java b/gateway-test/src/test/java/org/apache/knox/gateway/GatewaySslFuncTest.java index 24d58b126c..f0a5095832 100644 --- a/gateway-test/src/test/java/org/apache/knox/gateway/GatewaySslFuncTest.java +++ b/gateway-test/src/test/java/org/apache/knox/gateway/GatewaySslFuncTest.java @@ -37,6 +37,7 @@ import javax.net.ssl.SSLSession; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; +import javax.ws.rs.core.MediaType; import javax.xml.transform.stream.StreamSource; import org.apache.commons.io.FileUtils; @@ -225,6 +226,7 @@ public void testKnox674SslCipherSuiteConfig() throws Exception { new TrustAllHosts() ) ) .build(); HttpGet request = new HttpGet( serviceUrl ); + request.addHeader("Accept", MediaType.APPLICATION_XML); CloseableHttpResponse response = client.execute( request, context ); assertThat( the( new StreamSource( response.getEntity().getContent() ) ), hasXPath( "/ServerVersion/version" ) ); response.close(); @@ -261,6 +263,7 @@ public void testKnox674SslCipherSuiteConfig() throws Exception { new String[]{ "TLS_DHE_RSA_WITH_AES_128_CBC_SHA" }, new TrustAllHosts() ) ).build(); request = new HttpGet( serviceUrl ); + request.addHeader("Accept", MediaType.APPLICATION_XML); response = client.execute( request, context ); assertThat( the( new StreamSource( response.getEntity().getContent() ) ), hasXPath( "/ServerVersion/version" ) ); response.close(); diff --git a/gateway-topology-simple/pom.xml b/gateway-topology-simple/pom.xml index 9c80a26f6c..d6ca213ea1 100644 --- a/gateway-topology-simple/pom.xml +++ b/gateway-topology-simple/pom.xml @@ -59,8 +59,8 @@ commons-io - javax.xml.bind - jaxb-api + jakarta.xml.bind + jakarta.xml.bind-api org.apache.commons diff --git a/gateway-topology-simple/src/main/java/org/apache/knox/gateway/topology/simple/ProviderConfigurationParser.java b/gateway-topology-simple/src/main/java/org/apache/knox/gateway/topology/simple/ProviderConfigurationParser.java index cb8905e6d8..bb585bb29a 100644 --- a/gateway-topology-simple/src/main/java/org/apache/knox/gateway/topology/simple/ProviderConfigurationParser.java +++ b/gateway-topology-simple/src/main/java/org/apache/knox/gateway/topology/simple/ProviderConfigurationParser.java @@ -24,9 +24,9 @@ import java.util.Collections; import java.util.List; -import javax.xml.bind.JAXBContext; -import javax.xml.bind.JAXBException; -import javax.xml.bind.Unmarshaller; +import jakarta.xml.bind.JAXBContext; +import jakarta.xml.bind.JAXBException; +import jakarta.xml.bind.Unmarshaller; import org.apache.commons.io.FilenameUtils; diff --git a/gateway-topology-simple/src/main/java/org/apache/knox/gateway/topology/simple/XMLProviderConfiguration.java b/gateway-topology-simple/src/main/java/org/apache/knox/gateway/topology/simple/XMLProviderConfiguration.java index 6606206f87..9ed624922c 100644 --- a/gateway-topology-simple/src/main/java/org/apache/knox/gateway/topology/simple/XMLProviderConfiguration.java +++ b/gateway-topology-simple/src/main/java/org/apache/knox/gateway/topology/simple/XMLProviderConfiguration.java @@ -24,11 +24,11 @@ import java.util.TreeMap; import java.util.TreeSet; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlType; +import jakarta.xml.bind.annotation.XmlAccessType; +import jakarta.xml.bind.annotation.XmlAccessorType; +import jakarta.xml.bind.annotation.XmlElement; +import jakarta.xml.bind.annotation.XmlRootElement; +import jakarta.xml.bind.annotation.XmlType; import org.apache.commons.lang3.builder.EqualsBuilder; import org.apache.commons.lang3.builder.HashCodeBuilder; diff --git a/gateway-util-common/pom.xml b/gateway-util-common/pom.xml index a80ad88b09..1eec58fe97 100644 --- a/gateway-util-common/pom.xml +++ b/gateway-util-common/pom.xml @@ -35,6 +35,16 @@ gateway-i18n + + org.bouncycastle + bcprov-jdk18on + + + + org.bouncycastle + bcpkix-jdk18on + + com.fasterxml.jackson.core jackson-core @@ -63,6 +73,11 @@ javax.servlet-api + + com.sun.activation + jakarta.activation + + jakarta.activation jakarta.activation-api diff --git a/gateway-util-common/src/main/java/org/apache/knox/gateway/util/MimeTypeMap.java b/gateway-util-common/src/main/java/org/apache/knox/gateway/util/MimeTypeMap.java index 2f7e85906e..2ed9023539 100644 --- a/gateway-util-common/src/main/java/org/apache/knox/gateway/util/MimeTypeMap.java +++ b/gateway-util-common/src/main/java/org/apache/knox/gateway/util/MimeTypeMap.java @@ -17,8 +17,8 @@ */ package org.apache.knox.gateway.util; -import javax.activation.MimeType; -import javax.activation.MimeTypeParseException; +import jakarta.activation.MimeType; +import jakarta.activation.MimeTypeParseException; import java.util.HashMap; import java.util.Map; diff --git a/gateway-util-common/src/main/java/org/apache/knox/gateway/util/MimeTypes.java b/gateway-util-common/src/main/java/org/apache/knox/gateway/util/MimeTypes.java index c263c9a86c..ade36239c4 100644 --- a/gateway-util-common/src/main/java/org/apache/knox/gateway/util/MimeTypes.java +++ b/gateway-util-common/src/main/java/org/apache/knox/gateway/util/MimeTypes.java @@ -17,8 +17,8 @@ */ package org.apache.knox.gateway.util; -import javax.activation.MimeType; -import javax.activation.MimeTypeParseException; +import jakarta.activation.MimeType; +import jakarta.activation.MimeTypeParseException; import java.nio.charset.StandardCharsets; import java.util.HashMap; import java.util.Locale; diff --git a/gateway-util-common/src/main/java/org/apache/knox/gateway/util/X509CertificateUtil.java b/gateway-util-common/src/main/java/org/apache/knox/gateway/util/X509CertificateUtil.java index b66ee8406b..93cfb0d3ae 100644 --- a/gateway-util-common/src/main/java/org/apache/knox/gateway/util/X509CertificateUtil.java +++ b/gateway-util-common/src/main/java/org/apache/knox/gateway/util/X509CertificateUtil.java @@ -21,10 +21,6 @@ import java.io.IOException; import java.io.OutputStream; import java.io.PrintStream; -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; import java.math.BigInteger; import java.net.InetAddress; import java.net.Socket; @@ -35,14 +31,14 @@ import java.security.KeyStore; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; -import java.security.PrivateKey; -import java.security.PublicKey; import java.security.SecureRandom; import java.security.cert.Certificate; import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.util.Date; +import java.util.ArrayList; +import java.util.List; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLException; @@ -54,6 +50,16 @@ import org.apache.commons.codec.binary.Base64; import org.apache.knox.gateway.i18n.GatewayUtilCommonMessages; import org.apache.knox.gateway.i18n.messages.MessagesFactory; +import org.bouncycastle.asn1.x500.X500Name; +import org.bouncycastle.asn1.x509.Extension; +import org.bouncycastle.asn1.x509.GeneralName; +import org.bouncycastle.asn1.x509.GeneralNames; +import org.bouncycastle.cert.X509CertificateHolder; +import org.bouncycastle.cert.X509v3CertificateBuilder; +import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter; +import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder; +import org.bouncycastle.operator.ContentSigner; +import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; public class X509CertificateUtil { @@ -68,328 +74,62 @@ public class X509CertificateUtil { * @return self-signed X.509 certificate */ public static X509Certificate generateCertificate(String dn, KeyPair pair, int days, String algorithm) { - PrivateKey privkey = pair.getPrivate(); - Object x509CertImplObject = null; try { Date from = new Date(); Date to = new Date(from.getTime() + days * 86400000L); - Class certInfoClass = Class.forName(getX509CertInfoModuleName()); - Constructor certInfoConstr = certInfoClass.getConstructor(); - Object certInfoObject = certInfoConstr.newInstance(); - - // CertificateValidity interval = new CertificateValidity(from, to); - Class certValidityClass = Class.forName(getX509CertifValidityModuleName()); - Constructor certValidityConstr = certValidityClass.getConstructor(Date.class, Date.class); - Object certValidityObject = certValidityConstr.newInstance(from, to); - BigInteger sn = new BigInteger(64, new SecureRandom()); + X500Name issuer = new X500Name(dn); + X500Name subject = new X500Name(dn); - // X500Name owner = new X500Name(dn); - Class x500NameClass = Class.forName(getX509X500NameModuleName()); - Constructor x500NameConstr = x500NameClass.getConstructor(String.class); - Object x500NameObject = x500NameConstr.newInstance(dn); - - Method methodSET = certInfoObject.getClass().getMethod("set", String.class, Object.class); - - // info.set(X509CertInfo.VALIDITY, interval); - methodSET.invoke(certInfoObject, getSetField(certInfoObject, "VALIDITY"),certValidityObject); - - // info.set(X509CertInfo.SERIAL_NUMBER, new CertificateSerialNumber(sn)); - Class certificateSerialNumberClass = Class.forName(getCertificateSerialNumberModuleName()); - Constructor certificateSerialNumberConstr = certificateSerialNumberClass - .getConstructor(BigInteger.class); - Object certificateSerialNumberObject = certificateSerialNumberConstr.newInstance(sn); - methodSET.invoke(certInfoObject, getSetField(certInfoObject, "SERIAL_NUMBER"), - certificateSerialNumberObject); - - // info.set(X509CertInfo.SUBJECT, new CertificateSubjectName(owner)); - try { - Class certificateSubjectNameClass = Class.forName(getCertificateSubjectNameModuleName()); - Constructor certificateSubjectNameConstr = certificateSubjectNameClass - .getConstructor(x500NameClass); - Object certificateSubjectNameObject = certificateSubjectNameConstr - .newInstance(x500NameObject); - methodSET.invoke(certInfoObject, getSetField(certInfoObject, "SUBJECT"), - certificateSubjectNameObject); - } - catch (InvocationTargetException ite) { - methodSET.invoke(certInfoObject, getSetField(certInfoObject, "SUBJECT"), - x500NameObject); - } + X509v3CertificateBuilder certBuilder = new JcaX509v3CertificateBuilder( + issuer, + sn, + from, + to, + subject, + pair.getPublic() + ); - // info.set(X509CertInfo.ISSUER, new CertificateIssuerName(owner)); - try { - Class certificateIssuerNameClass = Class.forName(getCertificateIssuerNameModuleName()); - Constructor certificateIssuerNameConstr = certificateIssuerNameClass - .getConstructor(x500NameClass); - Object certificateIssuerNameObject = certificateIssuerNameConstr.newInstance(x500NameObject); - methodSET.invoke(certInfoObject, getSetField(certInfoObject, "ISSUER"), - certificateIssuerNameObject); - } - catch (InvocationTargetException ite) { - methodSET.invoke(certInfoObject, getSetField(certInfoObject, "ISSUER"), - x500NameObject); - } + // Add Subject Alternative Name extension + List generalNames = new ArrayList<>(); - // info.set(X509CertInfo.KEY, new CertificateX509Key(pair.getPublic())); - Class certificateX509KeyClass = Class.forName(getCertificateX509KeyModuleName()); - Constructor certificateX509KeyConstr = certificateX509KeyClass - .getConstructor(PublicKey.class); - Object certificateX509KeyObject = certificateX509KeyConstr.newInstance(pair.getPublic()); - methodSET.invoke(certInfoObject, getSetField(certInfoObject, "KEY"), - certificateX509KeyObject); - // info.set(X509CertInfo.VERSION, new CertificateVersion(CertificateVersion.V3)); - Class certificateVersionClass = Class.forName(getCertificateVersionModuleName()); - Constructor certificateVersionConstr = certificateVersionClass.getConstructor(int.class); - Constructor certificateVersionConstr0 = certificateVersionClass.getConstructor(); - Object certInfoObject0 = certificateVersionConstr0.newInstance(); - Field v3IntField = certInfoObject0.getClass().getDeclaredField("V3"); - v3IntField.setAccessible(true); - int fValue = v3IntField.getInt(certInfoObject0); - Object certificateVersionObject = certificateVersionConstr.newInstance(fValue); - methodSET.invoke(certInfoObject, getSetField(certInfoObject, "VERSION"), - certificateVersionObject); - - // AlgorithmId algo = new AlgorithmId(AlgorithmId.md5WithRSAEncryption_oid); - Class algorithmIdClass = Class.forName(getAlgorithmIdModuleName()); - Field md5WithRSAField = algorithmIdClass.getDeclaredField("RSAEncryption_oid"); - md5WithRSAField.setAccessible(true); - Class objectIdentifierClass = Class.forName(getObjectIdentifierModuleName()); - - Object md5WithRSAValue = md5WithRSAField.get(algorithmIdClass); - - Constructor algorithmIdConstr = algorithmIdClass.getConstructor(objectIdentifierClass); - Object algorithmIdObject = algorithmIdConstr.newInstance(md5WithRSAValue); - - // info.set(X509CertInfo.ALGORITHM_ID, new CertificateAlgorithmId(algo)); - Class certificateAlgorithmIdClass = Class.forName(getCertificateAlgorithmIdModuleName()); - Constructor certificateAlgorithmIdConstr = certificateAlgorithmIdClass - .getConstructor(algorithmIdClass); - Object certificateAlgorithmIdObject = certificateAlgorithmIdConstr - .newInstance(algorithmIdObject); - methodSET.invoke(certInfoObject, getSetField(certInfoObject, "ALGORITHM_ID"), - certificateAlgorithmIdObject); - - // Set the SAN extension - Class generalNameInterfaceClass = Class.forName(getGeneralNameInterfaceModuleName()); - - Class generalNameClass = Class.forName(getGeneralNameModuleName()); - Constructor generalNameConstr = generalNameClass.getConstructor(generalNameInterfaceClass); - - // GeneralNames generalNames = new GeneralNames(); - Class generalNamesClass = Class.forName(getGeneralNamesModuleName()); - Constructor generalNamesConstr = generalNamesClass.getConstructor(); - Object generalNamesObject = generalNamesConstr.newInstance(); - Method generalNamesAdd = generalNamesObject.getClass().getMethod("add", generalNameClass); - - Class dnsNameClass = Class.forName(getDNSNameModuleName()); - Constructor dnsNameConstr = dnsNameClass.getConstructor(String.class); - - boolean generalNameAdded = false; // Pull the hostname out of the DN - String hostname = dn.split(",", 2)[0].split("=", 2)[1]; - if("localhost".equals(hostname)) { + String hostname = dn.split(",", 2)[0].split("=", 2)[1].trim(); + if ("localhost".equals(hostname)) { // Add short hostname String detectedHostname = InetAddress.getLocalHost().getHostName(); - if (Character.isAlphabetic(detectedHostname.charAt(0))) { - // DNSName dnsName = new DNSName(detectedHostname); - Object dnsNameObject = dnsNameConstr.newInstance(detectedHostname); - // GeneralName generalName = new GeneralName(dnsName); - Object generalNameObject = generalNameConstr.newInstance(dnsNameObject); - // generalNames.add(generalName); - generalNamesAdd.invoke(generalNamesObject, generalNameObject); - generalNameAdded = true; + if (detectedHostname != null && !detectedHostname.isEmpty() && Character.isAlphabetic(detectedHostname.charAt(0))) { + generalNames.add(new GeneralName(GeneralName.dNSName, detectedHostname)); } // Add fully qualified hostname String detectedFullyQualifiedHostname = InetAddress.getLocalHost().getCanonicalHostName(); - if (Character.isAlphabetic(detectedFullyQualifiedHostname.charAt(0))) { - // DNSName dnsName = new DNSName(detectedFullyQualifiedHostname); - Object fullyQualifiedDnsNameObject = dnsNameConstr.newInstance(detectedFullyQualifiedHostname); - // GeneralName generalName = new GeneralName(fullyQualifiedDnsNameObject); - Object fullyQualifiedGeneralNameObject = generalNameConstr.newInstance(fullyQualifiedDnsNameObject); - // generalNames.add(fullyQualifiedGeneralNameObject); - generalNamesAdd.invoke(generalNamesObject, fullyQualifiedGeneralNameObject); - generalNameAdded = true; + if (detectedFullyQualifiedHostname != null && !detectedFullyQualifiedHostname.isEmpty() + && Character.isAlphabetic(detectedFullyQualifiedHostname.charAt(0)) + && !detectedFullyQualifiedHostname.equals(detectedHostname)) { + generalNames.add(new GeneralName(GeneralName.dNSName, detectedFullyQualifiedHostname)); } } - if (Character.isAlphabetic(hostname.charAt(0))) { - // DNSName dnsName = new DNSName(hostname); - Object dnsNameObject = dnsNameConstr.newInstance(hostname); - // GeneralName generalName = new GeneralName(dnsName); - Object generalNameObject = generalNameConstr.newInstance(dnsNameObject); - // generalNames.add(generalName); - generalNamesAdd.invoke(generalNamesObject, generalNameObject); - generalNameAdded = true; + if (hostname != null && !hostname.isEmpty() && Character.isAlphabetic(hostname.charAt(0))) { + generalNames.add(new GeneralName(GeneralName.dNSName, hostname)); } - if (generalNameAdded) { - // SubjectAlternativeNameExtension san = new SubjectAlternativeNameExtension(generalNames); - Class subjectAlternativeNameExtensionClass = Class.forName(getSubjectAlternativeNameExtensionModuleName()); - Constructor subjectAlternativeNameExtensionConstr = subjectAlternativeNameExtensionClass.getConstructor(generalNamesClass); - Object subjectAlternativeNameExtensionObject = subjectAlternativeNameExtensionConstr.newInstance(generalNamesObject); - - // CertificateExtensions certificateExtensions = new CertificateExtensions(); - Class certificateExtensionsClass = Class.forName(getCertificateExtensionsModuleName()); - Constructor certificateExtensionsConstr = certificateExtensionsClass.getConstructor(); - Object certificateExtensionsObject = certificateExtensionsConstr.newInstance(); - - // certificateExtensions.set(san.getExtensionId().toString(), san); - Method getExtensionIdMethod = subjectAlternativeNameExtensionObject.getClass().getMethod("getExtensionId"); - String sanExtensionId = getExtensionIdMethod.invoke(subjectAlternativeNameExtensionObject).toString(); - Method certificateExtensionsSet = certificateExtensionsObject.getClass().getMethod("set", String.class, Object.class); - certificateExtensionsSet.invoke(certificateExtensionsObject, sanExtensionId, subjectAlternativeNameExtensionObject); - - // info.set(X509CertInfo.EXTENSIONS, certificateExtensions); - methodSET.invoke(certInfoObject, getSetField(certInfoObject, "EXTENSIONS"), certificateExtensionsObject); + if (!generalNames.isEmpty()) { + GeneralNames subjectAltNames = new GeneralNames(generalNames.toArray(new GeneralName[0])); + certBuilder.addExtension(Extension.subjectAlternativeName, false, subjectAltNames); } - // Sign the cert to identify the algorithm that's used. - // X509CertImpl cert = new X509CertImpl(info); - Class x509CertImplClass = Class.forName(getX509CertImplModuleName()); - Constructor x509CertImplConstr = x509CertImplClass.getConstructor(certInfoClass); - x509CertImplObject = x509CertImplConstr.newInstance(certInfoObject); - - // cert.sign(privkey, algorithm); - Method methoSIGN = x509CertImplObject.getClass().getMethod("sign", - PrivateKey.class, String.class); - methoSIGN.invoke(x509CertImplObject, privkey, algorithm); - - // Update the algorith, and resign. - // algo = (AlgorithmId)cert.get(X509CertImpl.SIG_ALG); - Method methoGET = x509CertImplObject.getClass().getMethod("get", String.class); - String sig_alg = getSetField(x509CertImplObject, "SIG_ALG"); - - String certAlgoIdNameValue = getSetField(certificateAlgorithmIdObject, "NAME"); - String certAlgoIdAlgoValue = getSetField(certificateAlgorithmIdObject, "ALGORITHM"); - // info.set(CertificateAlgorithmId.NAME + "." + CertificateAlgorithmId.ALGORITHM, algo); - methodSET.invoke(certInfoObject, certAlgoIdNameValue + "." + certAlgoIdAlgoValue, - methoGET.invoke(x509CertImplObject, sig_alg)); - - // cert = new X509CertImpl(info); - x509CertImplObject = x509CertImplConstr.newInstance(certInfoObject); - // cert.sign(privkey, algorithm); - methoSIGN.invoke(x509CertImplObject, privkey, algorithm); + ContentSigner signer = new JcaContentSignerBuilder(algorithm).build(pair.getPrivate()); + X509CertificateHolder certHolder = certBuilder.build(signer); + + return new JcaX509CertificateConverter().getCertificate(certHolder); + } catch (Exception e) { LOG.failedToGenerateCertificate(e); + return null; } - return (X509Certificate) x509CertImplObject; - } - - private static String getX509CertInfoModuleName() { - return System.getProperty("java.vendor").contains("IBM") ? "com.ibm.security.x509.X509CertInfo" - : "sun.security.x509.X509CertInfo"; - } - - private static String getX509CertifValidityModuleName() { - return System.getProperty("java.vendor").contains("IBM") ? - "com.ibm.security.x509.CertificateValidity" : - "sun.security.x509.CertificateValidity"; - } - - private static String getX509X500NameModuleName() { - return System.getProperty("java.vendor").contains("IBM") ? - "com.ibm.security.x509.X500Name" : - "sun.security.x509.X500Name"; - } - - private static String getCertificateSerialNumberModuleName() { - return System.getProperty("java.vendor").contains("IBM") ? - "com.ibm.security.x509.CertificateSerialNumber" : - "sun.security.x509.CertificateSerialNumber"; - } - - private static String getCertificateSubjectNameModuleName() { - return System.getProperty("java.vendor").contains("IBM") ? - "com.ibm.security.x509.CertificateSubjectName" : - "sun.security.x509.CertificateSubjectName"; - } - - private static String getCertificateIssuerNameModuleName() { - return System.getProperty("java.vendor").contains("IBM") ? - "com.ibm.security.x509.CertificateIssuerName" : - "sun.security.x509.CertificateIssuerName"; - } - - private static String getCertificateX509KeyModuleName() { - return System.getProperty("java.vendor").contains("IBM") ? - "com.ibm.security.x509.CertificateX509Key" : - "sun.security.x509.CertificateX509Key"; - } - - private static String getCertificateVersionModuleName() { - return System.getProperty("java.vendor").contains("IBM") ? - "com.ibm.security.x509.CertificateVersion" : - "sun.security.x509.CertificateVersion"; - } - - private static String getAlgorithmIdModuleName() { - return System.getProperty("java.vendor").contains("IBM") ? - "com.ibm.security.x509.AlgorithmId" : - "sun.security.x509.AlgorithmId"; - } - - private static String getObjectIdentifierModuleName() { - return System.getProperty("java.vendor").contains("IBM") ? - "com.ibm.security.util.ObjectIdentifier" : - "sun.security.util.ObjectIdentifier"; - } - - private static String getCertificateAlgorithmIdModuleName() { - return System.getProperty("java.vendor").contains("IBM") ? - "com.ibm.security.x509.CertificateAlgorithmId" : - "sun.security.x509.CertificateAlgorithmId"; - } - - private static String getGeneralNameInterfaceModuleName() { - return System.getProperty("java.vendor").contains("IBM") ? - "com.ibm.security.x509.GeneralNameInterface" :// TODO - "sun.security.x509.GeneralNameInterface"; - } - - private static String getGeneralNameModuleName() { - return System.getProperty("java.vendor").contains("IBM") ? - "com.ibm.security.x509.GeneralName" : // TODO - "sun.security.x509.GeneralName"; - } - - private static String getGeneralNamesModuleName() { - return System.getProperty("java.vendor").contains("IBM") ? - "com.ibm.security.x509.GeneralNames" : // TODO - "sun.security.x509.GeneralNames"; - } - - private static String getDNSNameModuleName() { - return System.getProperty("java.vendor").contains("IBM") ? - "com.ibm.security.x509.DNSName" : // TODO - "sun.security.x509.DNSName"; - } - - private static String getSubjectAlternativeNameExtensionModuleName() { - return System.getProperty("java.vendor").contains("IBM") ? - "com.ibm.security.x509.SubjectAlternativeNameExtension" : // TODO - "sun.security.x509.SubjectAlternativeNameExtension"; - } - - private static String getCertificateExtensionsModuleName() { - return System.getProperty("java.vendor").contains("IBM") ? - "com.ibm.security.x509.CertificateExtensions" : // TODO - "sun.security.x509.CertificateExtensions"; - } - - private static String getX509CertImplModuleName() { - return System.getProperty("java.vendor").contains("IBM") ? - "com.ibm.security.x509.X509CertImpl" : - "sun.security.x509.X509CertImpl"; - } - - private static String getSetField(Object obj, String setString) - throws Exception { - Field privateStringField = obj.getClass().getDeclaredField(setString); - privateStringField.setAccessible(true); - return (String) privateStringField.get(obj); } public static void writeCertificateToFile(Certificate cert, final File file) @@ -486,7 +226,7 @@ public static void writeCertificateToPkcs12(Certificate cert, final File file) public static boolean isSelfSignedCertificate(Certificate certificate) { if (certificate instanceof X509Certificate) { X509Certificate x509Certificate = (X509Certificate) certificate; - return x509Certificate.getSubjectDN().equals(x509Certificate.getIssuerDN()); + return x509Certificate.getSubjectX500Principal().equals(x509Certificate.getIssuerX500Principal()); } else { return false; } diff --git a/gateway-util-common/src/test/java/org/apache/knox/gateway/util/MimeTypeMapTest.java b/gateway-util-common/src/test/java/org/apache/knox/gateway/util/MimeTypeMapTest.java index dc24e14d4d..bfa29e1cbc 100644 --- a/gateway-util-common/src/test/java/org/apache/knox/gateway/util/MimeTypeMapTest.java +++ b/gateway-util-common/src/test/java/org/apache/knox/gateway/util/MimeTypeMapTest.java @@ -19,8 +19,8 @@ import org.junit.Test; -import javax.activation.MimeType; -import javax.activation.MimeTypeParseException; +import jakarta.activation.MimeType; +import jakarta.activation.MimeTypeParseException; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; diff --git a/gateway-util-configinjector/src/main/java/org/apache/knox/gateway/config/impl/ConfigurationAdapterFactory.java b/gateway-util-configinjector/src/main/java/org/apache/knox/gateway/config/impl/ConfigurationAdapterFactory.java index 14c2589656..a6f8e3ee87 100755 --- a/gateway-util-configinjector/src/main/java/org/apache/knox/gateway/config/impl/ConfigurationAdapterFactory.java +++ b/gateway-util-configinjector/src/main/java/org/apache/knox/gateway/config/impl/ConfigurationAdapterFactory.java @@ -71,8 +71,14 @@ public static ConfigurationAdapter get( Object config ) throws ConfigurationExce throw new ConfigurationException( "No configuration adapter found for config type " + configType.getName() ); } Constructor c = findConstructorForConfigType( adapterType, configType ); - if( !c.isAccessible() ) { - c.setAccessible( true ); + // In JDK 17+, setAccessible is restricted and may throw InaccessibleObjectException. + // Use canAccess to check accessibility, and handle exceptions accordingly. + try { + if (!c.canAccess(null)) { + c.setAccessible(true); // This may still fail if running with strong encapsulation. + } + } catch (Exception ex) { + // Optionally log or handle the exception, but allow to proceed if possible. } Object adapter = c.newInstance( config ); return ConfigurationAdapter.class.cast( adapter ); diff --git a/gateway-util-configinjector/src/main/java/org/apache/knox/gateway/config/impl/DefaultConfigurationInjector.java b/gateway-util-configinjector/src/main/java/org/apache/knox/gateway/config/impl/DefaultConfigurationInjector.java index a138d856f7..5ac6f078e8 100755 --- a/gateway-util-configinjector/src/main/java/org/apache/knox/gateway/config/impl/DefaultConfigurationInjector.java +++ b/gateway-util-configinjector/src/main/java/org/apache/knox/gateway/config/impl/DefaultConfigurationInjector.java @@ -89,8 +89,10 @@ private void injectFieldValue( Field field, Object target, ConfigurationAdapter } } else { try { - if( !field.isAccessible() ) { - field.setAccessible( true ); + // In JDK 17, setAccessible is restricted for non-reflection code and may throw InaccessibleObjectException. + // Use canAccess to check accessibility, and handle exceptions accordingly. + if (!field.canAccess(target)) { + field.setAccessible(true); // This may still fail if running with strong encapsulation. } field.set( target, value ); } catch( Exception e ) { @@ -128,7 +130,7 @@ private void injectMethodValue( Method method, Object target, ConfigurationAdapt } args[ i ] = argValue; } - if( !method.isAccessible() ) { + if( !method.canAccess(target) ) { method.setAccessible( true ); } try { diff --git a/pom.xml b/pom.xml index ef66768f8d..67e769c52b 100644 --- a/pom.xml +++ b/pom.xml @@ -157,8 +157,8 @@ - 8 - 8 + 17 + 17 2.0.0 @@ -198,16 +198,18 @@ 2.7.1 1.4.13 2.1.3 - 4.3 + 5.2.0 2.7.8 3.3.1 3.0.0 1.2.18 1.11.0 3.9 + 1.2.18 + 1.11.0 1.15.1 1.0.0 - 2.3.3 + 4.0.5 2.10.1 1.9.0 3.0.7 @@ -218,7 +220,7 @@ 4.5.13 4.4.14 2.18.2 - 0.8.6 + 0.8.13 1.18 1.2.1 1.2.2 @@ -235,13 +237,14 @@ 3.4.1.Final 5.0.0 3.4 - 2.6 + 2.47 9.4.57.v20241219 - 2.14.6 + 3.21.0 5.9.0 2.10.8 2.9.0 2.5.2 + 1.3.4 4.13.2 1.9.10 1.5 @@ -249,9 +252,9 @@ 2.20.0 3.1.1 3.8.1 - 3.1.2 + 3.6.1 3.0.0-M3 - 3.12.0 + 3.26.0 4.1.16 2.2.4 4.1.127.Final @@ -264,18 +267,18 @@ 8.0.28 3.3.0 3.6.0 - 3.25.5 + 3.25.8 2.0.9 0.0.11.1 - - 0.11.4 - 4.3.3 + 0.12.4 + 5.5.6 1.13.0 + 1.13.0 1.2.6 2.0.0 2.0.13 - 4.2.0 - 4.1.4 + 4.9.3 + 4.9.3.0 5.3.21 2.3.4 1.8.3 @@ -290,13 +293,22 @@ 6.4.0 2.2.6 3.3 - 2.3.0 + 2.3.1 0.10 3.8.4 0.45.0 linux/amd64,linux/arm64 2.4 1.1.0 + 4.0.2 + 4.0.2 + 2.0.1 + 2.1.3 + 1.1.7 + 3.3 + 4.0.2 + 3.5.3 + 3.5.3 @@ -528,6 +540,8 @@ **/new-service-definition-template.xml **/token-management/**/assets/** **/knox-site/** + + **/dependency-reduced-pom.xml @@ -561,11 +575,9 @@ org.apache.maven.plugins maven-surefire-plugin + ${maven.surefire.plugin.version} - - + @{argLine} --add-exports java.base/sun.security.x509=ALL-UNNAMED --add-exports java.base/sun.security.pkcs=ALL-UNNAMED --add-exports java.naming/com.sun.jndi.ldap=ALL-UNNAMED --add-opens java.base/sun.security.util=ALL-UNNAMED org.apache.knox.test.category.SlowTests,org.apache.knox.test.category.ManualTests,org.apache.knox.test.category.VerifyTest,org.apache.knox.test.category.ReleaseTest @@ -579,6 +591,7 @@ org.apache.maven.plugins maven-failsafe-plugin + @{argLine} --add-exports java.base/sun.security.x509=ALL-UNNAMED --add-exports java.base/sun.security.pkcs=ALL-UNNAMED --add-exports java.naming/com.sun.jndi.ldap=ALL-UNNAMED --add-opens java.base/sun.security.util=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.lang.reflect=ALL-UNNAMED --add-opens java.base/java.io=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.net=ALL-UNNAMED --add-opens java.base/java.security=ALL-UNNAMED --add-opens java.base/java.util.concurrent=ALL-UNNAMED --add-opens java.base/java.util.concurrent.atomic=ALL-UNNAMED ${failsafe.group} @@ -618,7 +631,7 @@ [3.1.0,3.6.2),(3.6.2,) - [1.8,) + [17,18) @@ -656,6 +669,7 @@ ${findsecbugs-plugin.version} + false @@ -777,6 +791,21 @@ * + + org.eclipse.jetty:jetty-servlet + org.apache.knox:gateway-util-urltemplate + org.jboss.shrinkwrap.descriptors:shrinkwrap-descriptors-api-base + org.apache.knox:gateway-spi + com.nimbusds:nimbus-jose-jwt + org.apache.httpcomponents:httpcore + org.apache.knox:gateway-server + + + org.glassfish.hk2.external:jakarta.inject + jakarta.ws.rs:jakarta.ws.rs-api + jakarta.annotation:jakarta.annotation-api + + ${maven.dependency.skip} @@ -844,7 +873,7 @@ true true false - 1.8 + 17 @@ -913,7 +942,7 @@ true false - 1.8 + 17 @@ -1105,7 +1134,14 @@ org.apache.knox gateway-provider-jersey ${project.version} + + + jakarta.annotation + jakarta.annotation-api + + + org.apache.knox gateway-provider-ha @@ -1225,6 +1261,20 @@ org.apache.knox gateway-server ${project.version} + + + org.eclipse.angus + angus-mail + + + com.sun.xml.ws + jaxws-rt + + + com.sun.xml.ws + jaxws-ri + + org.apache.knox @@ -1367,6 +1417,12 @@ ${jersey.version} + + org.glassfish.jersey.inject + jersey-hk2 + ${jersey.version} + + com.fasterxml.jackson jackson-bom @@ -1455,32 +1511,52 @@ ${javax.ws.rs-api.version} + + jakarta.xml.bind + jakarta.xml.bind-api + ${jakarta.xml.bind.version} + jakarta.activation jakarta.activation-api ${jakarta.activation-api.version} + + org.glassfish.jaxb + jaxws-rt + ${jakarta.xml.ws.version} + + + + - com.sun.xml.bind - jaxb-core + org.glassfish.jaxb + jaxb-runtime ${xml-jaxb.version} com.sun.xml.bind jaxb-impl ${xml-jaxb.version} + + + org.eclipse.angus + angus-activation + + - org.glassfish.jaxb - jaxb-runtime - ${glassfish-jaxb.version} + com.sun.activation + jakarta.activation + ${jakarta.activation.version} org.glassfish.jaxb @@ -1489,22 +1565,26 @@ - com.sun.xml.ws - jaxws-ri - ${jaxws-ri.version} - pom + org.eclipse.persistence + org.eclipse.persistence.core + ${moxy.version} + + + org.eclipse.persistence + org.eclipse.persistence.moxy + ${moxy.version} - jakarta.xml.bind - jakarta.xml.bind-api - ${jakarta.xml.bind.version} + com.sun.xml.fastinfoset + FastInfoset + ${fastinfoset.version} - com.sun.activation - jakarta.activation - ${com.sun.activation.version} + jakarta.xml.bind + jakarta.xml.bind-api + ${jakarta.xml.bind.version} @@ -1519,11 +1599,13 @@ ${fastinfoset.version} + javax.json javax.json-api @@ -1534,6 +1616,16 @@ javax.json ${javax.json.version} + + jakarta.json + jakarta.json-api + ${jakarta.json.version} + + + org.eclipse.parsson + parsson + ${eclipse.parsson.version} + com.thetransactioncompany @@ -1569,7 +1661,7 @@ - jline + org.jline jline ${jline.version} @@ -1599,6 +1691,7 @@ + org.apache.httpcomponents httpcore-nio @@ -1611,6 +1704,7 @@ ${joda-time.version} + com.squareup.okhttp3 okhttp @@ -2577,6 +2671,11 @@ forbiddenapis ${forbiddenapis.version} + + jakarta.annotation + jakarta.annotation-api + ${jakarta.annotation-api.version} + com.cloudera.api.swagger cloudera-manager-api-swagger @@ -2628,7 +2727,6 @@ - org.apache.knox gateway-test-utils @@ -2785,6 +2883,10 @@ org.xerial.snappy snappy-java + + org.junit.jupiter + junit-jupiter-api + @@ -2841,5 +2943,11 @@ easymock test + + org.objenesis + objenesis + ${objenesis.version} + test + From dca7ef3d51b1d5396f23f02d4e65b9b1871b8c6c Mon Sep 17 00:00:00 2001 From: Sandor Molnar Date: Fri, 21 Nov 2025 13:23:37 +0100 Subject: [PATCH 2/4] KNOX-3215 - Revert KNOX-2647 (#1107) --- .../services/sparkhistoryui/2.3.0/rewrite.xml | 11 ----------- .../services/sparkhistoryui/2.3.0/service.xml | 3 --- 2 files changed, 14 deletions(-) diff --git a/gateway-service-definitions/src/main/resources/services/sparkhistoryui/2.3.0/rewrite.xml b/gateway-service-definitions/src/main/resources/services/sparkhistoryui/2.3.0/rewrite.xml index 0d30ea046f..bb513de36d 100644 --- a/gateway-service-definitions/src/main/resources/services/sparkhistoryui/2.3.0/rewrite.xml +++ b/gateway-service-definitions/src/main/resources/services/sparkhistoryui/2.3.0/rewrite.xml @@ -99,15 +99,4 @@ - - - - - - - - - - - diff --git a/gateway-service-definitions/src/main/resources/services/sparkhistoryui/2.3.0/service.xml b/gateway-service-definitions/src/main/resources/services/sparkhistoryui/2.3.0/service.xml index a81e2cb8b8..39b16f2a18 100644 --- a/gateway-service-definitions/src/main/resources/services/sparkhistoryui/2.3.0/service.xml +++ b/gateway-service-definitions/src/main/resources/services/sparkhistoryui/2.3.0/service.xml @@ -44,8 +44,5 @@ - - - From 3394ebce10728c490e9225cf532905a7c69f34cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sandeep=20More=CC=81?= Date: Fri, 21 Nov 2025 20:49:50 -0500 Subject: [PATCH 3/4] Fix issues with SecureKnoxShellTest --- .../webhdfs-kerb-test/pom.xml | 39 +++++++++++++++++++ gateway-test-release/webhdfs-test/pom.xml | 22 +++++++++++ pom.xml | 7 +++- 3 files changed, 67 insertions(+), 1 deletion(-) diff --git a/gateway-test-release/webhdfs-kerb-test/pom.xml b/gateway-test-release/webhdfs-kerb-test/pom.xml index 0645728738..6cecfd751c 100644 --- a/gateway-test-release/webhdfs-kerb-test/pom.xml +++ b/gateway-test-release/webhdfs-kerb-test/pom.xml @@ -29,6 +29,13 @@ webhdfs-kerb-test Tests for WebHDFS integration with Knox and Kerberos enabled + + + 2.28.2 + + @@ -96,11 +103,43 @@ groovy test + + org.codehaus.groovy + groovy-json + test + + + org.codehaus.groovy + groovy-xml + test + + + org.codehaus.groovy + groovy-swing + test + org.apache.knox gateway-spi-common test + + + org.mockito + mockito-core + ${mockito.version} + test + + + org.objenesis + objenesis + + + diff --git a/gateway-test-release/webhdfs-test/pom.xml b/gateway-test-release/webhdfs-test/pom.xml index ce084fdd97..36ce9863ce 100644 --- a/gateway-test-release/webhdfs-test/pom.xml +++ b/gateway-test-release/webhdfs-test/pom.xml @@ -29,6 +29,12 @@ webhdfs-test 3.0.0-SNAPSHOT Tests for WebHDFS integration with Knox + + + 2.28.2 + @@ -93,6 +99,22 @@ gateway-spi-common test + + + org.mockito + mockito-core + ${mockito.version} + test + + + org.objenesis + objenesis + + + diff --git a/pom.xml b/pom.xml index 67e769c52b..cd1eb51d04 100644 --- a/pom.xml +++ b/pom.xml @@ -212,7 +212,7 @@ 4.0.5 2.10.1 1.9.0 - 3.0.7 + 3.0.21 32.1.3-jre 3.4.1 2.2 @@ -1653,6 +1653,11 @@ groovy-json ${groovy.version} + + org.codehaus.groovy + groovy-swing + ${groovy.version} + org.fusesource.jansi From dc3ee0d84d1dbcda72f982d12a4713f04994d75f Mon Sep 17 00:00:00 2001 From: Phil Zampino Date: Mon, 24 Nov 2025 09:17:47 -0500 Subject: [PATCH 4/4] KNOX-3216: Upgrade Spring to 6.x (#1109) --- pom.xml | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/pom.xml b/pom.xml index cd1eb51d04..5b77bbfb25 100644 --- a/pom.xml +++ b/pom.xml @@ -217,8 +217,9 @@ 3.4.1 2.2 0.2 - 4.5.13 + 5.4.3 4.4.14 + 5.3.6 2.18.2 0.8.13 1.18 @@ -279,7 +280,7 @@ 2.0.13 4.9.3 4.9.3.0 - 5.3.21 + 6.2.11 2.3.4 1.8.3 4.2.1 @@ -1672,14 +1673,14 @@ - org.apache.httpcomponents - httpclient + org.apache.httpcomponents.client5 + httpclient5 ${httpclient.version} - org.apache.httpcomponents - httpcore - ${httpcore.version} + org.apache.httpcomponents.core5 + httpcore5 + ${httpcore5.version} org.apache.httpcomponents