Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rest Client Reactive - support for quarkus.tls.trust-all #16685

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -41,6 +41,16 @@
<artifactId>assertj-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.github.tomakehurst</groupId>
<artifactId>wiremock-jre8</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<build>
Expand Down
@@ -0,0 +1,63 @@
package io.quarkus.rest.client.reactive.ssl;

import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig;
import static org.assertj.core.api.Assertions.assertThat;

import java.net.URI;

import javax.ws.rs.GET;
import javax.ws.rs.Path;

import org.eclipse.microprofile.rest.client.RestClientBuilder;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import com.github.tomakehurst.wiremock.WireMockServer;
import com.github.tomakehurst.wiremock.client.WireMock;

import io.quarkus.test.QuarkusUnitTest;

public class TrustAllTest {

@RegisterExtension
static final QuarkusUnitTest TEST = new QuarkusUnitTest()
.setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class)
.addClasses(Client.class))
.withConfigurationResource("trust-all-test-application.properties");

WireMockServer server;
URI baseUri;

@BeforeEach
public void setUp() {
server = new WireMockServer(wireMockConfig().dynamicHttpsPort());
server.stubFor(WireMock.get("/ssl")
.willReturn(aResponse().withBody("hello").withStatus(200)));
server.start();
baseUri = URI.create("https://localhost:" + server.httpsPort());
}

@AfterEach
public void cleanUp() {
server.shutdown();
}

@Test
void shouldWorkWithTrustAllAndSelfSignedCert() {
Client client = RestClientBuilder.newBuilder()
.baseUri(baseUri)
.build(Client.class);
assertThat(client.get()).isEqualTo("hello");
}

@Path("ssl")
interface Client {
@GET
String get();
}
}
@@ -0,0 +1 @@
quarkus.tls.trust-all=true
Expand Up @@ -37,6 +37,7 @@
public class RestClientBuilderImpl implements RestClientBuilder {

private static final String DEFAULT_MAPPER_DISABLED = "microprofile.rest.client.disable.default.mapper";
private static final String TLS_TRUST_ALL = "quarkus.tls.trust-all";

private final ClientBuilderImpl clientBuilder = (ClientBuilderImpl) new ClientBuilderImpl()
.withConfig(new ConfigurationImpl(RuntimeType.CLIENT));
Expand Down Expand Up @@ -250,8 +251,13 @@ public <T> T build(Class<T> aClass) throws IllegalStateException, RestClientDefi

clientBuilder.multiQueryParamMode(toMultiQueryParamMode(queryParamStyle));

ClientImpl client = (ClientImpl) clientBuilder.build();
WebTargetImpl target = null;
Boolean trustAll = ConfigProvider.getConfig().getOptionalValue(TLS_TRUST_ALL, Boolean.class)
.orElse(false);

clientBuilder.trustAll(trustAll);

ClientImpl client = clientBuilder.build();
WebTargetImpl target;
try {
target = (WebTargetImpl) client.target(url.toURI());
} catch (URISyntaxException e) {
Expand Down
Expand Up @@ -45,10 +45,6 @@ public class RestClientCDIDelegateBuilder {

private static final String MAX_REDIRECTS = "quarkus.rest.client.max-redirects";

private static final String TLS_TRUST_ALL = "quarkus.tls.trust-all";

private static final String REST_NOOP_HOSTNAME_VERIFIER = "io.quarkus.restclient.NoopHostnameVerifier";

private final Class<?> jaxrsInterface;
private final String baseUriFromAnnotation;
private final String propertyPrefix;
Expand All @@ -74,8 +70,7 @@ private Object build() {
configureRedirects(builder);
configureQueryParamStyle(builder);
configureProxy(builder);
Object result = builder.build(jaxrsInterface);
return result;
return builder.build(jaxrsInterface);
}

private void configureProxy(RestClientBuilder builder) {
Expand All @@ -90,9 +85,9 @@ private void configureProxy(RestClientBuilder builder) {
}

String host = proxyString.substring(0, lastColonIndex);
int port = 0;
int port;
try {
port = Integer.valueOf(proxyString.substring(lastColonIndex + 1));
port = Integer.parseInt(proxyString.substring(lastColonIndex + 1));
} catch (NumberFormatException e) {
throw new RuntimeException("Invalid proxy setting. The port is not a number in '" + proxyString + "'", e);
}
Expand Down Expand Up @@ -124,11 +119,6 @@ private void configureRedirects(RestClientBuilder builder) {

private void configureSsl(RestClientBuilder builder) {

Optional<Boolean> trustAll = getOptionalProperty(TLS_TRUST_ALL, Boolean.class);
if (trustAll.isPresent() && trustAll.get()) {
registerHostnameVerifier(REST_NOOP_HOSTNAME_VERIFIER, builder);
}

Optional<String> maybeTrustStore = getOptionalDynamicProperty(REST_TRUST_STORE, String.class);
if (maybeTrustStore.isPresent()) {
registerTrustStore(maybeTrustStore.get(), builder);
Expand Down
Expand Up @@ -43,6 +43,8 @@ public class ClientBuilderImpl extends ClientBuilder {
private String proxyHost;
private int proxyPort;
private boolean followRedirects;
private boolean trustAll;

private MultiQueryParamMode multiQueryParamMode;

private HttpClientOptions httpClientOptions = new HttpClientOptions();
Expand Down Expand Up @@ -128,6 +130,11 @@ public ClientImpl build() {

HttpClientOptions options = httpClientOptions == null ? new HttpClientOptions() : httpClientOptions;

if (trustAll) {
options.setTrustAll(true);
options.setVerifyHost(false);
}

if (keyStore != null || trustStore != null) {
options = options.setSsl(true);
if (keyStore != null) {
Expand Down Expand Up @@ -232,4 +239,9 @@ public ClientBuilderImpl register(Object component, Map<Class<?>, Integer> contr
configuration.register(component, contracts);
return this;
}

public ClientBuilderImpl trustAll(boolean trustAll) {
this.trustAll = trustAll;
return this;
}
}