Skip to content

Commit

Permalink
[fixes quarkusio#8508] - missing documentation for HTTPS with 2way TL…
Browse files Browse the repository at this point in the history
…S (aka mutual TLS, aka client cert auth)
  • Loading branch information
pedroigor committed Apr 28, 2020
1 parent 78405ae commit 65cd7eb
Show file tree
Hide file tree
Showing 6 changed files with 91 additions and 0 deletions.
25 changes: 25 additions & 0 deletions docs/src/main/asciidoc/security.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,31 @@ The following properties can be used to configure form based auth:

include::{generated-dir}/config/quarkus-vertx-http-config-group-form-auth-config.adoc[opts=optional, leveloffset=+1]

=== Mutual TLS Client Authentication

Quarkus provides mTLS client authentication so that your application can authenticate peers based on X.509 certificates. To authenticate using this method, the TLS connection between the peer and the application must have been established and you need to configure the server to request certificates from peers as well as configure your peers to provide their certificates.

From an application perspective, you should have a configuration similar to this:

[source,properties]
--
quarkus.http.ssl.certificate.key-store-file=server-keystore.jks <1>
quarkus.http.ssl.certificate.key-store-password=password <2>
quarkus.http.ssl.certificate.trust-store-file=server-truststore.jks <3>
quarkus.http.ssl.certificate.trust-store-password=password <4>
quarkus.http.ssl.client-auth=REQUIRED <5>
--

<1> The keystore where both private key and certificates of the application are being stored
<2> The keystore password
<3> The truststore where you store the certificates of the peers that you want to authenticate and accept requests from
<4> The truststore password
<5> Defines that the application should always request certificate from peers (`REQUIRED`). You may also use `REQUEST` in case you only want to authenticate if the client presents a certificate

The steps <1> and <2> are basically enabling HTTP/TLS to your application. Whereas steps <3> to <5> configure the server to authenticate using mTLS client authentication.

include::{generated-dir}/config/quarkus-vertx-http-config-group-server-ssl-config.adoc[opts=optional, leveloffset=+1]

=== Proactive Authentication

By default Quarkus does what we call proactive authentication. This means that if an incoming request has a
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package io.quarkus.vertx.http.ssl;

import static org.hamcrest.core.Is.is;

import java.io.File;
import java.net.URL;

import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.event.Observes;
import javax.net.ssl.SSLPeerUnverifiedException;

import org.assertj.core.api.Assertions;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.quarkus.test.QuarkusUnitTest;
import io.quarkus.test.common.http.TestHTTPResource;
import io.restassured.RestAssured;
import io.vertx.ext.web.Router;

public class MtlsTest {

@TestHTTPResource(value = "/mtls", ssl = true)
URL url;

@RegisterExtension
static final QuarkusUnitTest config = new QuarkusUnitTest()
.setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class)
.addClasses(MyBean.class)
.addAsResource(new File("src/test/resources/conf/mtls-jks.conf"), "application.properties")
.addAsResource(new File("src/test/resources/conf/server-keystore.jks"), "server-keystore.jks")
.addAsResource(new File("src/test/resources/conf/server-truststore.jks"), "server-truststore.jks"));

@Test
public void testSslServerWithJKS() {
RestAssured.given()
.keyStore(new File("src/test/resources/conf/client-keystore.jks"), "password")
.trustStore(new File("src/test/resources/conf/client-truststore.jks"), "password")
.get(url).then().statusCode(200).body(is("CN=client,OU=cert,O=quarkus,L=city,ST=state,C=AU"));
}

@ApplicationScoped
static class MyBean {

public void register(@Observes Router router) {
router.get("/mtls").handler(rc -> {
Assertions.assertThat(rc.request().connection().isSsl()).isTrue();
Assertions.assertThat(rc.request().isSSL()).isTrue();
Assertions.assertThat(rc.request().connection().sslSession()).isNotNull();
try {
rc.response().end(rc.request().connection().sslSession().getPeerPrincipal().getName());
} catch (SSLPeerUnverifiedException cause) {
throw new RuntimeException("Failed to obtain peer principal", cause);
}
});
}

}
}
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
quarkus.http.ssl.certificate.key-store-file=server-keystore.jks
quarkus.http.ssl.certificate.key-store-password=secret
quarkus.http.ssl.certificate.trust-store-file=server-truststore.jks
quarkus.http.ssl.certificate.trust-store-password=password
quarkus.http.ssl.client-auth=REQUIRED
Binary file not shown.

0 comments on commit 65cd7eb

Please sign in to comment.