This is an automated email from the ASF dual-hosted git repository.
lmccay pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/knox.git
The following commit(s) were added to refs/heads/master by this push:
new b26b8de23 KNOX-3099: Ability to exclude topologies form client auth
needed policy (#995)
b26b8de23 is described below
commit b26b8de23abf9aa585de1b1e33834427697c05b1
Author: hanicz <[email protected]>
AuthorDate: Wed Feb 26 19:01:50 2025 +0100
KNOX-3099: Ability to exclude topologies form client auth needed policy
(#995)
* KNOX-3099: Ability to exclude topologies form client auth needed policy
via (hanicz)
---
.../org/apache/knox/gateway/GatewayMessages.java | 3 ++
.../org/apache/knox/gateway/GatewayServer.java | 1 +
.../gateway/config/impl/GatewayConfigImpl.java | 10 +++++
.../services/security/impl/JettySSLService.java | 10 +++++
.../knox/gateway/GatewayGlobalConfigTest.java | 11 +++++
.../security/impl/JettySSLServiceTest.java | 52 ++++++++++++++++++++++
.../test/resources/conf-site/conf/gateway-site.xml | 6 +++
.../org/apache/knox/gateway/GatewayTestConfig.java | 5 +++
.../apache/knox/gateway/config/GatewayConfig.java | 2 +
.../knox/gateway/services/security/SSLService.java | 3 ++
10 files changed, 103 insertions(+)
diff --git
a/gateway-server/src/main/java/org/apache/knox/gateway/GatewayMessages.java
b/gateway-server/src/main/java/org/apache/knox/gateway/GatewayMessages.java
index 6b97ac713..c6363c4ce 100644
--- a/gateway-server/src/main/java/org/apache/knox/gateway/GatewayMessages.java
+++ b/gateway-server/src/main/java/org/apache/knox/gateway/GatewayMessages.java
@@ -806,4 +806,7 @@ public interface GatewayMessages {
@Message(level = MessageLevel.INFO,
text = "Starting gateway status service. Topologies to check: {0}")
void startingStatusMonitor(Set<String> topologyNames);
+
+ @Message( level = MessageLevel.INFO, text = "Excluded \"{0}\" topology from
client auth" )
+ void topologyExcludedFromClientAuth( String topologyName );
}
diff --git
a/gateway-server/src/main/java/org/apache/knox/gateway/GatewayServer.java
b/gateway-server/src/main/java/org/apache/knox/gateway/GatewayServer.java
index 2d6fd3a2a..fc037b9c7 100644
--- a/gateway-server/src/main/java/org/apache/knox/gateway/GatewayServer.java
+++ b/gateway-server/src/main/java/org/apache/knox/gateway/GatewayServer.java
@@ -440,6 +440,7 @@ public class GatewayServer {
httpsConfig.addCustomizer( new SecureRequestCustomizer() );
SSLService ssl = services.getService(ServiceType.SSL_SERVICE);
SslContextFactory sslContextFactory =
(SslContextFactory)ssl.buildSslContextFactory( config );
+ ssl.excludeTopologyFromClientAuth(sslContextFactory, config,
topologyName);
connector = new ServerConnector( server, sslContextFactory, new
HttpConnectionFactory( httpsConfig ) );
} else {
connector = new ServerConnector(server, new
HttpConnectionFactory(httpConfig));
diff --git
a/gateway-server/src/main/java/org/apache/knox/gateway/config/impl/GatewayConfigImpl.java
b/gateway-server/src/main/java/org/apache/knox/gateway/config/impl/GatewayConfigImpl.java
index 9b178df70..1e5166f24 100644
---
a/gateway-server/src/main/java/org/apache/knox/gateway/config/impl/GatewayConfigImpl.java
+++
b/gateway-server/src/main/java/org/apache/knox/gateway/config/impl/GatewayConfigImpl.java
@@ -117,6 +117,7 @@ public class GatewayConfigImpl extends Configuration
implements GatewayConfig {
public static final String FRONTEND_URL = GATEWAY_CONFIG_FILE_PREFIX +
".frontend.url";
private static final String TRUST_ALL_CERTS = GATEWAY_CONFIG_FILE_PREFIX +
".trust.all.certs";
private static final String CLIENT_AUTH_NEEDED = GATEWAY_CONFIG_FILE_PREFIX
+ ".client.auth.needed";
+ private static final String CLIENT_AUTH_EXCLUDE = GATEWAY_CONFIG_FILE_PREFIX
+ ".client.auth.exclude";
private static final String CLIENT_AUTH_WANTED = GATEWAY_CONFIG_FILE_PREFIX
+ ".client.auth.wanted";
private static final String KEYSTORE_TYPE = GATEWAY_CONFIG_FILE_PREFIX +
".keystore.type";
private static final String KEYSTORE_CACHE_LIMIT =
GATEWAY_CONFIG_FILE_PREFIX + ".keystore.cache.size.limit";
@@ -690,6 +691,15 @@ public class GatewayConfigImpl extends Configuration
implements GatewayConfig {
return Boolean.parseBoolean(get( CLIENT_AUTH_NEEDED, "false" ));
}
+ @Override
+ public boolean isTopologyExcludedFromClientAuth(String topologyName) {
+ String clientAuthExcludeConfig = get(CLIENT_AUTH_EXCLUDE, null);
+ if(clientAuthExcludeConfig == null || topologyName == null) {
+ return false;
+ }
+ return clientAuthExcludeConfig.contains(topologyName);
+ }
+
@Override
public boolean isClientAuthWanted() {
return Boolean.parseBoolean(get( CLIENT_AUTH_WANTED, "false" ));
diff --git
a/gateway-server/src/main/java/org/apache/knox/gateway/services/security/impl/JettySSLService.java
b/gateway-server/src/main/java/org/apache/knox/gateway/services/security/impl/JettySSLService.java
index 002914053..782d07902 100644
---
a/gateway-server/src/main/java/org/apache/knox/gateway/services/security/impl/JettySSLService.java
+++
b/gateway-server/src/main/java/org/apache/knox/gateway/services/security/impl/JettySSLService.java
@@ -236,6 +236,16 @@ public class JettySSLService implements SSLService {
return sslContextFactory;
}
+ @Override
+ public void excludeTopologyFromClientAuth(SslContextFactory
sslContextFactory, GatewayConfig config, String topologyName) {
+ if(config.isClientAuthNeeded() &&
config.isTopologyExcludedFromClientAuth(topologyName)) {
+ SslContextFactory.Server sslContextFactoryServer =
(SslContextFactory.Server) sslContextFactory;
+ sslContextFactoryServer.setNeedClientAuth(false);
+ sslContextFactoryServer.setWantClientAuth(true);
+ log.topologyExcludedFromClientAuth(topologyName);
+ }
+ }
+
@Override
public void start() throws ServiceLifecycleException {
}
diff --git
a/gateway-server/src/test/java/org/apache/knox/gateway/GatewayGlobalConfigTest.java
b/gateway-server/src/test/java/org/apache/knox/gateway/GatewayGlobalConfigTest.java
index 970b08786..9f95899a4 100644
---
a/gateway-server/src/test/java/org/apache/knox/gateway/GatewayGlobalConfigTest.java
+++
b/gateway-server/src/test/java/org/apache/knox/gateway/GatewayGlobalConfigTest.java
@@ -30,6 +30,7 @@ import java.security.KeyStore;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
@@ -48,6 +49,7 @@ public class GatewayGlobalConfigTest {
GatewayConfig config = new GatewayConfigImpl();
assertThat( config.getGatewayPort(), is( 7777 ) );
assertThat( config.isClientAuthNeeded(), is( false ) );
+ assertFalse( config.isTopologyExcludedFromClientAuth("health"));
assertNull("ssl.exclude.protocols should be null.",
config.getExcludedSSLProtocols());
//assertThat( config.getShiroConfigFile(), is( "full-shiro.ini") );
}
@@ -67,11 +69,20 @@ public class GatewayGlobalConfigTest {
GatewayConfig config = new GatewayConfigImpl();
assertThat( config.getGatewayPort(), is( 5555 ) );
assertThat( config.isClientAuthNeeded(), is( true ) );
+ assertTrue( config.isTopologyExcludedFromClientAuth("health"));
assertThat( config.getTruststorePath(), is("./gateway-trust.jks"));
assertThat( config.getTruststoreType(), is( "PKCS12" ) );
assertThat( config.getKeystoreType(), is(KeyStore.getDefaultType()) );
}
+ @Test
+ public void testSiteConfigWithDifferentTopologyExcluded() {
+ System.setProperty( GatewayConfigImpl.GATEWAY_HOME_VAR, getHomeDirName(
"conf-site/conf/gateway-site.xml" ) );
+ GatewayConfig config = new GatewayConfigImpl();
+ assertThat( config.isClientAuthNeeded(), is( true ) );
+ assertFalse( config.isTopologyExcludedFromClientAuth("different"));
+ }
+
@Test
public void testEmptyConfig() {
System.setProperty( GatewayConfigImpl.GATEWAY_HOME_VAR, getHomeDirName(
"conf-empty/conf/empty" ) );
diff --git
a/gateway-server/src/test/java/org/apache/knox/gateway/services/security/impl/JettySSLServiceTest.java
b/gateway-server/src/test/java/org/apache/knox/gateway/services/security/impl/JettySSLServiceTest.java
index ec67c77b7..6491ddfea 100644
---
a/gateway-server/src/test/java/org/apache/knox/gateway/services/security/impl/JettySSLServiceTest.java
+++
b/gateway-server/src/test/java/org/apache/knox/gateway/services/security/impl/JettySSLServiceTest.java
@@ -453,6 +453,51 @@ public class JettySSLServiceTest {
fail("UnrecoverableKeyException should have been thrown");
}
+ @Test
+ public void testExcludeTopologyFromClientAuth() {
+ SslContextFactory.Server sslContextFactory = new
SslContextFactory.Server();
+ sslContextFactory.setNeedClientAuth(true);
+ GatewayConfig config = createGatewayConfigForExcludeTopologyTest(true,
true, "health");
+ replay(config);
+
+ JettySSLService sslService = new JettySSLService();
+ sslService.excludeTopologyFromClientAuth(sslContextFactory,
config,"health");
+
+ verify(config);
+ assertFalse(sslContextFactory.getNeedClientAuth());
+ assertTrue(sslContextFactory.getWantClientAuth());
+ }
+
+ @Test
+ public void testExcludeTopologyFromClientAuthNoExclude() {
+ SslContextFactory.Server sslContextFactory = new
SslContextFactory.Server();
+ sslContextFactory.setNeedClientAuth(true);
+ GatewayConfig config = createGatewayConfigForExcludeTopologyTest(true,
false, "health");
+ replay(config);
+
+ JettySSLService sslService = new JettySSLService();
+ sslService.excludeTopologyFromClientAuth(sslContextFactory,
config,"health");
+
+ verify(config);
+ assertTrue(sslContextFactory.getNeedClientAuth());
+ assertFalse(sslContextFactory.getWantClientAuth());
+ }
+
+ @Test
+ public void testExcludeTopologyFromClientAuthNoPolicy() {
+ SslContextFactory.Server sslContextFactory = new
SslContextFactory.Server();
+ sslContextFactory.setNeedClientAuth(false);
+ GatewayConfig config = createGatewayConfigForExcludeTopologyTest(false,
true, "health");
+ replay(config);
+
+ JettySSLService sslService = new JettySSLService();
+ sslService.excludeTopologyFromClientAuth(sslContextFactory,
config,"health");
+
+ verify(config);
+ assertFalse(sslContextFactory.getNeedClientAuth());
+ assertFalse(sslContextFactory.getWantClientAuth());
+ }
+
private GatewayConfig createGatewayConfig(boolean isClientAuthNeeded,
boolean isExplicitTruststore,
Path identityKeystorePath, String
identityKeystoreType,
String identityKeyAlias, Path
truststorePath,
@@ -486,4 +531,11 @@ public class JettySSLServiceTest {
return config;
}
+ private GatewayConfig createGatewayConfigForExcludeTopologyTest(boolean
isClientAuthNeeded, boolean isTopologyExcluded, String topologyName) {
+ GatewayConfig config = createMock(GatewayConfig.class);
+
expect(config.isClientAuthNeeded()).andReturn(isClientAuthNeeded).anyTimes();
+
expect(config.isTopologyExcludedFromClientAuth(topologyName)).andReturn(isTopologyExcluded).anyTimes();
+ return config;
+ }
+
}
\ No newline at end of file
diff --git a/gateway-server/src/test/resources/conf-site/conf/gateway-site.xml
b/gateway-server/src/test/resources/conf-site/conf/gateway-site.xml
index 5815b84ac..ccc179dbe 100644
--- a/gateway-server/src/test/resources/conf-site/conf/gateway-site.xml
+++ b/gateway-server/src/test/resources/conf-site/conf/gateway-site.xml
@@ -55,6 +55,12 @@ limitations under the License.
<description>mutual authentication required for all
topologies</description>
</property>
+ <property>
+ <name>gateway.client.auth.exclude</name>
+ <value>health</value>
+ <description>topologies to be excluded from client auth needed
policy</description>
+ </property>
+
<property>
<name>gateway.truststore.path</name>
<value>./gateway-trust.jks</value>
diff --git
a/gateway-spi-common/src/main/java/org/apache/knox/gateway/GatewayTestConfig.java
b/gateway-spi-common/src/main/java/org/apache/knox/gateway/GatewayTestConfig.java
index 6905b557b..ae42f95f1 100644
---
a/gateway-spi-common/src/main/java/org/apache/knox/gateway/GatewayTestConfig.java
+++
b/gateway-spi-common/src/main/java/org/apache/knox/gateway/GatewayTestConfig.java
@@ -344,6 +344,11 @@ public class GatewayTestConfig extends Configuration
implements GatewayConfig {
return false;
}
+ @Override
+ public boolean isTopologyExcludedFromClientAuth(String topology) {
+ return false;
+ }
+
@Override
public String getTruststorePath() {
return null;
diff --git
a/gateway-spi/src/main/java/org/apache/knox/gateway/config/GatewayConfig.java
b/gateway-spi/src/main/java/org/apache/knox/gateway/config/GatewayConfig.java
index fa6a017fc..c773a8c5b 100644
---
a/gateway-spi/src/main/java/org/apache/knox/gateway/config/GatewayConfig.java
+++
b/gateway-spi/src/main/java/org/apache/knox/gateway/config/GatewayConfig.java
@@ -207,6 +207,8 @@ public interface GatewayConfig {
boolean isClientAuthNeeded();
+ boolean isTopologyExcludedFromClientAuth(String topologyName);
+
boolean isClientAuthWanted();
String getTruststorePath();
diff --git
a/gateway-spi/src/main/java/org/apache/knox/gateway/services/security/SSLService.java
b/gateway-spi/src/main/java/org/apache/knox/gateway/services/security/SSLService.java
index 6b135dea6..5787ea027 100644
---
a/gateway-spi/src/main/java/org/apache/knox/gateway/services/security/SSLService.java
+++
b/gateway-spi/src/main/java/org/apache/knox/gateway/services/security/SSLService.java
@@ -19,7 +19,10 @@ package org.apache.knox.gateway.services.security;
import org.apache.knox.gateway.config.GatewayConfig;
import org.apache.knox.gateway.services.Service;
+import org.eclipse.jetty.util.ssl.SslContextFactory;
public interface SSLService extends Service {
Object buildSslContextFactory(GatewayConfig config) throws
AliasServiceException;
+
+ void excludeTopologyFromClientAuth(SslContextFactory sslContextFactory,
GatewayConfig config, String topologyName);
}