From c2e54fd80a0161336cdf1e8e5b9af4b02f0eed8a Mon Sep 17 00:00:00 2001 From: Peter Palaga Date: Fri, 15 Mar 2024 16:12:47 +0100 Subject: [PATCH] MutualTlsTest.mTls() fails on Quarkus Platform fix #1292 --- .../cxf/QuarkusHTTPConduitFactory.java | 15 ++++--- .../cxf/it/auth/mtls/MutualTlsTest.java | 45 ++++++++++++++++--- 2 files changed, 49 insertions(+), 11 deletions(-) diff --git a/extensions/core/runtime/src/main/java/io/quarkiverse/cxf/QuarkusHTTPConduitFactory.java b/extensions/core/runtime/src/main/java/io/quarkiverse/cxf/QuarkusHTTPConduitFactory.java index 41752eada..bb3217bb1 100644 --- a/extensions/core/runtime/src/main/java/io/quarkiverse/cxf/QuarkusHTTPConduitFactory.java +++ b/extensions/core/runtime/src/main/java/io/quarkiverse/cxf/QuarkusHTTPConduitFactory.java @@ -28,6 +28,7 @@ import org.apache.cxf.transport.http.URLConnectionHTTPConduit; import org.apache.cxf.transports.http.configuration.HTTPClientPolicy; import org.apache.cxf.ws.addressing.EndpointReferenceType; +import org.jboss.logging.Logger; import io.quarkiverse.cxf.CxfClientConfig.HTTPConduitImpl; import io.quarkiverse.cxf.CxfClientConfig.WellKnownHostnameVerifier; @@ -38,7 +39,7 @@ * @since 3.8.1 */ public class QuarkusHTTPConduitFactory implements HTTPConduitFactory { - + private static final Logger log = Logger.getLogger(QuarkusHTTPConduitFactory.class); private final CxfFixedConfig cxFixedConfig; private final CXFClientInfo cxfClientInfo; private final boolean hc5Present; @@ -106,7 +107,7 @@ public HTTPConduit createConduit(HTTPTransportFactory f, Bus b, EndpointInfo loc return configure(result, cxfClientInfo); } - private HTTPConduit configure(HTTPConduit httpConduit, CXFClientInfo cxfClientInfo) { + private HTTPConduit configure(HTTPConduit httpConduit, CXFClientInfo cxfClientInfo) throws IOException { final String hostnameVerifierName = cxfClientInfo.getHostnameVerifier(); final String keyStorePath = cxfClientInfo.getKeyStore(); final String trustStorePath = cxfClientInfo.getTrustStore(); @@ -139,7 +140,7 @@ private HTTPConduit configure(HTTPConduit httpConduit, CXFClientInfo cxfClientIn kmf.init(keyStore, (keyPassword != null) ? keyPassword.toCharArray() : null); } catch (IOException | NoSuchAlgorithmException | CertificateException | KeyStoreException | UnrecoverableKeyException e) { - throw new RuntimeException("Could not load " + keyStorePath + " from class path", e); + throw new RuntimeException("Could not load " + keyStorePath + " from class path or filesystem", e); } tlsCP.setKeyManagers(kmf.getKeyManagers()); } @@ -154,7 +155,7 @@ private HTTPConduit configure(HTTPConduit httpConduit, CXFClientInfo cxfClientIn tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); tmf.init(trustStore); } catch (IOException | NoSuchAlgorithmException | CertificateException | KeyStoreException e) { - throw new RuntimeException("Could not load " + trustStorePath + " from class path", e); + throw new RuntimeException("Could not load " + trustStorePath + " from class path or filesystem", e); } tlsCP.setTrustManagers(tmf.getTrustManagers()); } @@ -263,7 +264,7 @@ private HTTPConduit configure(HTTPConduit httpConduit, CXFClientInfo cxfClientIn return httpConduit; } - private InputStream openStream(final String keystorePath) { + private InputStream openStream(final String keystorePath) throws IOException { final URL url = Thread.currentThread().getContextClassLoader().getResource(keystorePath); if (url != null) { try { @@ -280,7 +281,9 @@ private InputStream openStream(final String keystorePath) { throw new RuntimeException("Could not open " + keystorePath + " from the filesystem", e); } } - throw new IllegalStateException("Resource " + keystorePath + " exists neither in class path nor in the filesystem"); + final String msg = "Resource " + keystorePath + " exists neither in class path nor in the filesystem"; + log.error(msg); + throw new IllegalStateException(msg); } } diff --git a/integration-tests/mtls/src/test/java/io/quarkiverse/cxf/it/auth/mtls/MutualTlsTest.java b/integration-tests/mtls/src/test/java/io/quarkiverse/cxf/it/auth/mtls/MutualTlsTest.java index a0ea3936a..0bd628487 100644 --- a/integration-tests/mtls/src/test/java/io/quarkiverse/cxf/it/auth/mtls/MutualTlsTest.java +++ b/integration-tests/mtls/src/test/java/io/quarkiverse/cxf/it/auth/mtls/MutualTlsTest.java @@ -1,7 +1,12 @@ package io.quarkiverse.cxf.it.auth.mtls; -import static org.hamcrest.Matchers.is; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardCopyOption; +import org.assertj.core.api.Assertions; import org.eclipse.microprofile.config.ConfigProvider; import org.hamcrest.Matchers; import org.junit.jupiter.api.Test; @@ -10,19 +15,49 @@ import io.restassured.RestAssured; import io.restassured.config.RestAssuredConfig; import io.restassured.config.SSLConfig; +import io.restassured.response.ExtractableResponse; +import io.restassured.response.Response; @QuarkusTest public class MutualTlsTest { @Test - void mTls() { - RestAssured.given() + void mTls() throws IOException { + + final Path keystorePath = Path + .of(ConfigProvider.getConfig().getValue("quarkus.cxf.client.mTls.key-store", String.class)); + extract(keystorePath); + + final Path truststorePath = Path + .of(ConfigProvider.getConfig().getValue("quarkus.cxf.client.mTls.trust-store", String.class)); + extract(truststorePath); + + ExtractableResponse response = RestAssured.given() .config(restAssuredConfig()) .body("Sam") .post("https://localhost:8444/cxf/mtls-rest/mTls") .then() - .statusCode(200) - .body(is("Hello Sam authenticated by mTLS!")); + .extract(); + if (response.statusCode() != 200) { + Assertions.fail("Expected 200, got " + response.statusCode() + ": " + response.body().asString()); + } else { + Assertions.assertThat(response.body().asString()).isEqualTo("Hello Sam authenticated by mTLS!"); + } + } + private void extract(final Path keystorePath) throws IOException { + Assertions.assertThat(keystorePath.getName(0).toString()).isEqualTo("target"); + if (!Files.isRegularFile(keystorePath)) { + /* + * This test can be run from the test jar on Quarkus Platform + * In that case target/classes does not exist an we have to copy + * what's needed manually + */ + Files.createDirectories(keystorePath.getParent()); + try (InputStream in = MutualTlsTest.class.getClassLoader() + .getResourceAsStream(keystorePath.getFileName().toString())) { + Files.copy(in, keystorePath, StandardCopyOption.REPLACE_EXISTING); + } + } } @Test