Skip to content

Commit 7352bcc

Browse files
committed
Quarkus HTTPS with KeyStore SPI
Signed-off-by: Tero Saarni <[email protected]>
1 parent 2417350 commit 7352bcc

File tree

2 files changed

+70
-8
lines changed

2 files changed

+70
-8
lines changed
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/*
2+
* Copyright 2022 Red Hat, Inc. and/or its affiliates
3+
* and other contributors as indicated by the @author tags.
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package org.keycloak.quarkus.runtime;
18+
19+
import org.jboss.logging.Logger;
20+
import org.keycloak.models.KeycloakSession;
21+
import org.keycloak.quarkus.runtime.integration.QuarkusKeycloakSessionFactory;
22+
import org.keycloak.keystore.KeyStoreProvider;
23+
24+
import java.security.InvalidAlgorithmParameterException;
25+
import java.security.KeyStore;
26+
import java.security.NoSuchAlgorithmException;
27+
28+
import javax.net.ssl.KeyManagerFactory;
29+
import javax.net.ssl.KeyStoreBuilderParameters;
30+
import javax.net.ssl.X509KeyManager;
31+
32+
import io.quarkus.vertx.http.HttpServerOptionsCustomizer;
33+
import io.vertx.core.http.HttpServerOptions;
34+
import io.vertx.core.net.KeyCertOptions;
35+
import jakarta.enterprise.context.ApplicationScoped;
36+
37+
@ApplicationScoped
38+
public class VertxCustomizer implements HttpServerOptionsCustomizer {
39+
40+
private static final Logger log = Logger.getLogger(VertxCustomizer.class);
41+
42+
@Override
43+
public void customizeHttpsServer(HttpServerOptions options) {
44+
try {
45+
QuarkusKeycloakSessionFactory instance = QuarkusKeycloakSessionFactory.getInstance();
46+
KeycloakSession session = instance.create();
47+
48+
KeyStore.Builder ksb = session.getProvider(KeyStoreProvider.class)
49+
.loadKeyStoreBuilder(KeyStoreProvider.HTTPS_SERVER_KEYSTORE);
50+
if (ksb != null) {
51+
log.info("Setting KeyStore to Vert.x");
52+
KeyManagerFactory kmf = KeyManagerFactory.getInstance("NewSunX509");
53+
kmf.init(new KeyStoreBuilderParameters(ksb));
54+
KeyCertOptions kco = KeyCertOptions.wrap((X509KeyManager) kmf.getKeyManagers()[0]);
55+
options.setKeyCertOptions(kco);
56+
}
57+
} catch (NoSuchAlgorithmException | InvalidAlgorithmParameterException e) {
58+
log.error("Failed to set KeyManager: " + e.toString());
59+
throw new RuntimeException("Failed to set KeyManager: " + e.toString());
60+
}
61+
62+
}
63+
}

quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/configuration/mappers/HttpPropertyMappers.java

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -64,25 +64,25 @@ public static PropertyMapper[] getHttpPropertyMappers() {
6464
.paramLabel("protocols")
6565
.build(),
6666
fromOption(HttpOptions.HTTPS_CERTIFICATE_FILE)
67-
.to("quarkus.http.ssl.certificate.files")
67+
.to("kc.spi-keystore-default-https-certificate-file")
6868
.paramLabel("file")
6969
.build(),
7070
fromOption(HttpOptions.HTTPS_CERTIFICATE_KEY_FILE)
71-
.to("quarkus.http.ssl.certificate.key-files")
71+
.to("kc.spi-keystore-default-https-certificate-key-file")
7272
.paramLabel("file")
7373
.build(),
7474
fromOption(HttpOptions.HTTPS_KEY_STORE_FILE
75-
.withRuntimeSpecificDefault(getDefaultKeystorePathValue()))
76-
.to("quarkus.http.ssl.certificate.key-store-file")
75+
.withRuntimeSpecificDefault(getDefaultKeystorePathValue()))
76+
.to("kc.spi-keystore-default-https-keystore-file")
7777
.paramLabel("file")
7878
.build(),
7979
fromOption(HttpOptions.HTTPS_KEY_STORE_PASSWORD)
80-
.to("quarkus.http.ssl.certificate.key-store-password")
80+
.to("kc.spi-keystore-default-https-keystore-password")
8181
.paramLabel("password")
8282
.isMasked(true)
8383
.build(),
8484
fromOption(HttpOptions.HTTPS_KEY_STORE_TYPE)
85-
.to("quarkus.http.ssl.certificate.key-store-file-type")
85+
.to("kc.spi-keystore-default-https-keystore-type")
8686
.mapFrom(SecurityOptions.FIPS_MODE.getKey())
8787
.transformer(HttpPropertyMappers::resolveKeyStoreType)
8888
.paramLabel("type")
@@ -118,7 +118,7 @@ private static Optional<String> getHttpEnabledTransformer(Optional<String> value
118118
ConfigValue proceed = context.proceed("kc.https-certificate-file");
119119

120120
if (proceed == null || proceed.getValue() == null) {
121-
proceed = getMapper("quarkus.http.ssl.certificate.key-store-file").getConfigValue(context);
121+
proceed = getMapper("kc.spi-keystore-default-https-keystore-file").getConfigValue(context);
122122
}
123123

124124
if (proceed == null || proceed.getValue() == null) {
@@ -157,4 +157,3 @@ private static Optional<String> resolveKeyStoreType(Optional<String> value,
157157
return value;
158158
}
159159
}
160-

0 commit comments

Comments
 (0)