Skip to content

Commit

Permalink
Introduce quarkus.cxf.client.tls-configuration-name property
Browse files Browse the repository at this point in the history
  • Loading branch information
dcheng1248 committed Feb 15, 2025
1 parent 125d8f9 commit c072d9d
Show file tree
Hide file tree
Showing 6 changed files with 560 additions and 28 deletions.
25 changes: 25 additions & 0 deletions docs/modules/ROOT/pages/reference/extensions/quarkus-cxf.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -563,6 +563,29 @@ public class MyRestEasyResource {
*Environment variable*: `+++QUARKUS_CXF_DECOUPLED_ENDPOINT_BASE+++` +
*Since Quarkus CXF*: 2.7.0

.<| [[quarkus-cxf_quarkus-cxf-client-tls-configuration-name]]`link:#quarkus-cxf_quarkus-cxf-client-tls-configuration-name[quarkus.cxf.client.tls-configuration-name]`
.<| `string`
.<| `javax.net.ssl`

3+a|The name of the TLS configuration to use for setting up trust store and keystore for all clients. This setting can be
overridden per client using
`xref:#quarkus-cxf_quarkus-cxf-client-client-name-tls-configuration-name[quarkus.cxf.client."client-name".tls-configuration-name]`

For each client, if the per-client `.tls-configuration-name` or `.trust-store` or `.key-store` is configured then the
relevant per client configuration will be used.
Otherwise, this configuration will be used.

By default, if the `javax.net.ssl.trustStore` system property is defined, then its value is honored as a truststore
Otherwise, the paths `$JAVA_HOME/lib/security/jssecacerts` and `$JAVA_HOME/lib/security/cacerts` are checked
and the first existing file is used as a truststore
Otherwise an `IllegalStateException` is thrown.

The password for opening the truststore is taken from the `javax.net.ssl.trustStorePassword` system property.
If it is not set, the default password `changeit` is used.

*Environment variable*: `+++QUARKUS_CXF_CLIENT_TLS_CONFIGURATION_NAME+++` +
*Since Quarkus CXF*: 3.19.0

.<| [[quarkus-cxf_quarkus-cxf-logging-enabled-for]]`link:#quarkus-cxf_quarkus-cxf-logging-enabled-for[quarkus.cxf.logging.enabled-for]`
.<| `clients`, `services`, `both`, `none`
.<| `none`
Expand Down Expand Up @@ -2054,6 +2077,8 @@ and `.key-store*` family of options will be used.
If a name is configured, it uses the configuration from `quarkus.tls.<name>.*`
If a name is configured, but no TLS configuration is found with that name then an error will be thrown at runtime.
Setting `.tls-configuration-name` and any of `.trust-store` or `.key-store` leads to an exception at runtime.
If none of `.tls-configuration-name`, `.trust-store` or `.key-store` is set, the default configuration is given by
`xref:#quarkus-cxf_quarkus-cxf-client-tls-configuration-name[quarkus.cxf.client.tls-configuration-name]`

*Environment variable*: `+++QUARKUS_CXF_CLIENT__CLIENT_NAME__TLS_CONFIGURATION_NAME+++` +
*Since Quarkus CXF*: 3.15.0
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
package io.quarkiverse.cxf.deployment.test;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.file.Path;
import java.security.KeyStore;

import jakarta.annotation.PostConstruct;
import jakarta.enterprise.inject.Instance;
import jakarta.inject.Inject;
import jakarta.jws.WebMethod;
import jakarta.jws.WebService;
Expand All @@ -12,6 +19,7 @@
import org.jboss.logging.Logger;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

Expand Down Expand Up @@ -44,69 +52,247 @@ public class TlsConfigurationTest {
HelloServiceImpl.class.getName())
.overrideConfigKey("quarkus.cxf.endpoint.\"/hello\".logging.enabled", "true")

/* Default Quarkus TLS configuration for the clients */
.overrideConfigKey("quarkus.tls.trust-store.p12.path", "target/classes/localhost-truststore.p12")
.overrideConfigKey("quarkus.tls.trust-store.p12.password", "secret")

/* Named TLS configuration for the clients */
.overrideConfigKey("quarkus.tls.client-pkcs12.trust-store.p12.path", "target/classes/localhost-truststore.p12")
.overrideConfigKey("quarkus.tls.client-pkcs12.trust-store.p12.password", "secret")

/* Client with VertxHttpClientHTTPConduitFactory */
/*
* Client with VertxHttpClientHTTPConduitFactory
* Clients 1 and 2 test the java.net.ssl.trustStore
* Clients 3 and 4 test the default Quarkus TLS configurations
* Clients 5 and 6 test the named TLS configurations
*/
.overrideConfigKey("quarkus.cxf.client.helloVertx.client-endpoint-url", "https://localhost:8444/services/hello")
.overrideConfigKey("quarkus.cxf.client.helloVertx.logging.enabled", "true")
.overrideConfigKey("quarkus.cxf.client.helloVertx.service-interface", HelloService.class.getName())
.overrideConfigKey("quarkus.cxf.client.helloVertx.http-conduit-factory", "VertxHttpClientHTTPConduitFactory")
.overrideConfigKey("quarkus.cxf.client.helloVertx.tls-configuration-name", "client-pkcs12")

.overrideConfigKey("quarkus.cxf.client.helloVertx2.client-endpoint-url", "https://localhost:8444/services/hello")
.overrideConfigKey("quarkus.cxf.client.helloVertx2.logging.enabled", "true")
.overrideConfigKey("quarkus.cxf.client.helloVertx2.service-interface", HelloService.class.getName())
.overrideConfigKey("quarkus.cxf.client.helloVertx2.http-conduit-factory", "VertxHttpClientHTTPConduitFactory")
.overrideConfigKey("quarkus.cxf.client.helloVertx2.tls-configuration-name", "client-pkcs12")

.overrideConfigKey("quarkus.cxf.client.helloVertx3.client-endpoint-url", "https://localhost:8444/services/hello")
.overrideConfigKey("quarkus.cxf.client.helloVertx3.logging.enabled", "true")
.overrideConfigKey("quarkus.cxf.client.helloVertx3.service-interface", HelloService.class.getName())
.overrideConfigKey("quarkus.cxf.client.helloVertx3.http-conduit-factory", "VertxHttpClientHTTPConduitFactory")
.overrideConfigKey("quarkus.cxf.client.helloVertx3.tls-configuration-name", "<default>")

.overrideConfigKey("quarkus.cxf.client.helloVertx4.client-endpoint-url", "https://localhost:8444/services/hello")
.overrideConfigKey("quarkus.cxf.client.helloVertx4.logging.enabled", "true")
.overrideConfigKey("quarkus.cxf.client.helloVertx4.service-interface", HelloService.class.getName())
.overrideConfigKey("quarkus.cxf.client.helloVertx4.http-conduit-factory", "VertxHttpClientHTTPConduitFactory")
.overrideConfigKey("quarkus.cxf.client.helloVertx4.tls-configuration-name", "<default>")

.overrideConfigKey("quarkus.cxf.client.helloVertx5.client-endpoint-url", "https://localhost:8444/services/hello")
.overrideConfigKey("quarkus.cxf.client.helloVertx5.logging.enabled", "true")
.overrideConfigKey("quarkus.cxf.client.helloVertx5.service-interface", HelloService.class.getName())
.overrideConfigKey("quarkus.cxf.client.helloVertx5.http-conduit-factory", "VertxHttpClientHTTPConduitFactory")
.overrideConfigKey("quarkus.cxf.client.helloVertx5.tls-configuration-name", "client-pkcs12")

.overrideConfigKey("quarkus.cxf.client.helloVertx6.client-endpoint-url", "https://localhost:8444/services/hello")
.overrideConfigKey("quarkus.cxf.client.helloVertx6.logging.enabled", "true")
.overrideConfigKey("quarkus.cxf.client.helloVertx6.service-interface", HelloService.class.getName())
.overrideConfigKey("quarkus.cxf.client.helloVertx6.http-conduit-factory", "VertxHttpClientHTTPConduitFactory")
.overrideConfigKey("quarkus.cxf.client.helloVertx6.tls-configuration-name", "client-pkcs12")

/* Client with HttpClientHTTPConduitFactory */
.overrideConfigKey("quarkus.cxf.client.helloHttpClient.client-endpoint-url",
"https://localhost:8444/services/hello")
.overrideConfigKey("quarkus.cxf.client.helloHttpClient.logging.enabled", "true")
.overrideConfigKey("quarkus.cxf.client.helloHttpClient.service-interface", HelloService.class.getName())
.overrideConfigKey("quarkus.cxf.client.helloHttpClient.http-conduit-factory", "HttpClientHTTPConduitFactory")
.overrideConfigKey("quarkus.cxf.client.helloHttpClient.tls-configuration-name", "client-pkcs12")

.overrideConfigKey("quarkus.cxf.client.helloHttpClient2.client-endpoint-url",
"https://localhost:8444/services/hello")
.overrideConfigKey("quarkus.cxf.client.helloHttpClient2.logging.enabled", "true")
.overrideConfigKey("quarkus.cxf.client.helloHttpClient2.service-interface", HelloService.class.getName())
.overrideConfigKey("quarkus.cxf.client.helloHttpClient2.http-conduit-factory", "HttpClientHTTPConduitFactory")
.overrideConfigKey("quarkus.cxf.client.helloHttpClient2.tls-configuration-name", "<default>")

.overrideConfigKey("quarkus.cxf.client.helloHttpClient3.client-endpoint-url",
"https://localhost:8444/services/hello")
.overrideConfigKey("quarkus.cxf.client.helloHttpClient3.logging.enabled", "true")
.overrideConfigKey("quarkus.cxf.client.helloHttpClient3.service-interface", HelloService.class.getName())
.overrideConfigKey("quarkus.cxf.client.helloHttpClient3.http-conduit-factory", "HttpClientHTTPConduitFactory")
.overrideConfigKey("quarkus.cxf.client.helloHttpClient3.tls-configuration-name", "client-pkcs12")

/* Client with URLConnectionHTTPConduitFactory */
.overrideConfigKey("quarkus.cxf.client.helloUrlConnection.client-endpoint-url",
"https://localhost:8444/services/hello")
.overrideConfigKey("quarkus.cxf.client.helloUrlConnection.logging.enabled", "true")
.overrideConfigKey("quarkus.cxf.client.helloUrlConnection.service-interface", HelloService.class.getName())
.overrideConfigKey("quarkus.cxf.client.helloUrlConnection.http-conduit-factory", "URLConnectionHTTPConduitFactory")
.overrideConfigKey("quarkus.cxf.client.helloUrlConnection.tls-configuration-name", "client-pkcs12");

@CXFClient("helloVertx")
.overrideConfigKey("quarkus.cxf.client.helloUrlConnection2.client-endpoint-url",
"https://localhost:8444/services/hello")
.overrideConfigKey("quarkus.cxf.client.helloUrlConnection2.logging.enabled", "true")
.overrideConfigKey("quarkus.cxf.client.helloUrlConnection2.service-interface", HelloService.class.getName())
.overrideConfigKey("quarkus.cxf.client.helloUrlConnection2.http-conduit-factory", "URLConnectionHTTPConduitFactory")
.overrideConfigKey("quarkus.cxf.client.helloUrlConnection2.tls-configuration-name", "<default>")

.overrideConfigKey("quarkus.cxf.client.helloUrlConnection3.client-endpoint-url",
"https://localhost:8444/services/hello")
.overrideConfigKey("quarkus.cxf.client.helloUrlConnection3.logging.enabled", "true")
.overrideConfigKey("quarkus.cxf.client.helloUrlConnection3.service-interface", HelloService.class.getName())
.overrideConfigKey("quarkus.cxf.client.helloUrlConnection3.http-conduit-factory", "URLConnectionHTTPConduitFactory")
.overrideConfigKey("quarkus.cxf.client.helloUrlConnection3.tls-configuration-name", "client-pkcs12");

HelloService helloVertx;

@CXFClient("helloVertx2")
HelloService helloVertx2;

@CXFClient("helloHttpClient")
@CXFClient("helloVertx")
Instance<HelloService> helloVertxInstance;

@CXFClient("helloVertx2")
Instance<HelloService> helloVertxInstance2;

@CXFClient("helloVertx3")
HelloService helloVertx3;

@CXFClient("helloVertx4")
HelloService helloVertx4;

@CXFClient("helloVertx5")
HelloService helloVertx5;

@CXFClient("helloVertx6")
HelloService helloVertx6;

HelloService helloHttpClient;

@CXFClient("helloUrlConnection")
@CXFClient("helloHttpClient")
Instance<HelloService> helloHttpClientInstance;

@CXFClient("helloHttpClient2")
HelloService helloHttpClient2;

@CXFClient("helloHttpClient3")
HelloService helloHttpClient3;

HelloService helloUrlConnection;

@CXFClient("helloUrlConnection")
Instance<HelloService> helloUrlConnectionInstance;

@CXFClient("helloUrlConnection2")
HelloService helloUrlConnection2;

@CXFClient("helloUrlConnection3")
HelloService helloUrlConnection3;

@Inject
Logger logger;

@PostConstruct
void setup() throws Exception {
addCertToDefaultCacert();
this.helloVertx = helloVertxInstance.get();
this.helloVertx2 = helloVertxInstance2.get();
this.helloHttpClient = helloHttpClientInstance.get();
this.helloUrlConnection = helloUrlConnectionInstance.get();
}

@AfterAll
public static void cleanup() throws Exception {
removeCertFromDefaultCacert();
}

private static void addCertToDefaultCacert() throws Exception {
String cacertsPath = System.getProperty("java.home") + "/lib/security/cacerts";
String cacertsPassword = "changeit";

KeyStore cacerts = KeyStore.getInstance(KeyStore.getDefaultType());
try (FileInputStream cacertsInput = new FileInputStream(cacertsPath)) {
cacerts.load(cacertsInput, cacertsPassword.toCharArray());
}

Path p12FilePath = Path.of("target/classes/localhost-truststore.p12");
String p12Password = "secret";
KeyStore p12Store = KeyStore.getInstance("PKCS12");
try (FileInputStream p12Input = new FileInputStream(p12FilePath.toFile())) {
p12Store.load(p12Input, p12Password.toCharArray());
}

java.security.cert.Certificate cert = p12Store.getCertificate("localhost");
cacerts.setCertificateEntry("localhost", cert);

try (FileOutputStream cacertsOutput = new FileOutputStream(cacertsPath)) {
cacerts.store(cacertsOutput, cacertsPassword.toCharArray());
}

System.out.println("Successfully updated cacerts with certificates from the P12 file.");
}

public static void removeCertFromDefaultCacert() throws Exception {
String cacertsPath = System.getProperty("java.home") + "/lib/security/cacerts";
String cacertsPassword = "changeit";

KeyStore cacerts = KeyStore.getInstance(KeyStore.getDefaultType());
try (FileInputStream cacertsInput = new FileInputStream(cacertsPath)) {
cacerts.load(cacertsInput, cacertsPassword.toCharArray());
}

if (cacerts.containsAlias("localhost")) {
cacerts.deleteEntry("localhost");

try (FileOutputStream cacertsOutput = new FileOutputStream(cacertsPath)) {
cacerts.store(cacertsOutput, cacertsPassword.toCharArray());
}
System.out.println("Removed certificate with alias localhost");
}
}

@Test
void vertx() {
void vertxJVMDefault() {
Assertions.assertThat(helloVertx.hello("Doe")).isEqualTo("Hello Doe");
}

@Test
void httpClient() {
void vertxQuarkusDefault() {
Assertions.assertThat(helloVertx3.hello("Doe")).isEqualTo("Hello Doe");
}

@Test
void vertxNamed() {
Assertions.assertThat(helloVertx5.hello("Doe")).isEqualTo("Hello Doe");
}

@Test
void httpClientJVMDefault() {
Assertions.assertThat(helloHttpClient.hello("Doe")).isEqualTo("Hello Doe");
}

@Test
void urlConnection() {
void httpClientQuarkusDefault() {
Assertions.assertThat(helloHttpClient2.hello("Doe")).isEqualTo("Hello Doe");
}

@Test
void httpClientNamed() {
Assertions.assertThat(helloHttpClient3.hello("Doe")).isEqualTo("Hello Doe");
}

@Test
void urlConnectionJVMDefault() {
Assertions.assertThat(helloUrlConnection.hello("Doe")).isEqualTo("Hello Doe");
}

@Test
void urlConnectionQuarkusDefault() {
Assertions.assertThat(helloUrlConnection2.hello("Doe")).isEqualTo("Hello Doe");
}

@Test
void urlConnectionNamed() {
Assertions.assertThat(helloUrlConnection3.hello("Doe")).isEqualTo("Hello Doe");
}

@Test
void sameTlsConfiguration() {

Expand All @@ -115,14 +301,25 @@ void sameTlsConfiguration() {
* work
*/

TLSClientParameters p1 = getTLSClientParameters(helloVertx2);
TLSClientParameters p2 = getTLSClientParameters(helloVertx);
TLSClientParameters p1 = getTLSClientParameters(helloVertx);
TLSClientParameters p2 = getTLSClientParameters(helloVertx2);
TLSClientParameters p3 = getTLSClientParameters(helloVertx3);
TLSClientParameters p4 = getTLSClientParameters(helloVertx4);
TLSClientParameters p5 = getTLSClientParameters(helloVertx5);
TLSClientParameters p6 = getTLSClientParameters(helloVertx6);

Assertions.assertThat(p1).isNotNull().isInstanceOf(QuarkusTLSClientParameters.class);
Assertions.assertThat(p2).isNotNull().isInstanceOf(QuarkusTLSClientParameters.class);
Assertions.assertThat(p3).isNotNull().isInstanceOf(QuarkusTLSClientParameters.class);
Assertions.assertThat(p4).isNotNull().isInstanceOf(QuarkusTLSClientParameters.class);
Assertions.assertThat(p5).isNotNull().isInstanceOf(QuarkusTLSClientParameters.class);
Assertions.assertThat(p6).isNotNull().isInstanceOf(QuarkusTLSClientParameters.class);
Assertions.assertThat(((QuarkusTLSClientParameters) p1).getTlsConfiguration())
.isSameAs(((QuarkusTLSClientParameters) p2).getTlsConfiguration());

Assertions.assertThat(((QuarkusTLSClientParameters) p3).getTlsConfiguration())
.isSameAs(((QuarkusTLSClientParameters) p4).getTlsConfiguration());
Assertions.assertThat(((QuarkusTLSClientParameters) p5).getTlsConfiguration())
.isSameAs(((QuarkusTLSClientParameters) p6).getTlsConfiguration());
}

static TLSClientParameters getTLSClientParameters(HelloService cl) {
Expand Down
Loading

0 comments on commit c072d9d

Please sign in to comment.