diff --git a/docs/src/main/asciidoc/security-oidc-code-flow-authentication.adoc b/docs/src/main/asciidoc/security-oidc-code-flow-authentication.adoc index c8330c4b7c90a..dfd7245c4b89c 100644 --- a/docs/src/main/asciidoc/security-oidc-code-flow-authentication.adoc +++ b/docs/src/main/asciidoc/security-oidc-code-flow-authentication.adoc @@ -197,7 +197,7 @@ quarkus.oidc.credentials.jwt.key-file=privateKey.pem ---- quarkus.oidc.auth-server-url=http://localhost:8180/realms/quarkus/ quarkus.oidc.client-id=quarkus-app -quarkus.oidc.credentials.jwt.key-store-file=keystore.jks +quarkus.oidc.credentials.jwt.key-store-file=keystore.pkcs12 quarkus.oidc.credentials.jwt.key-store-password=mypassword quarkus.oidc.credentials.jwt.key-password=mykeypassword diff --git a/docs/src/main/asciidoc/security-openid-connect-client-reference.adoc b/docs/src/main/asciidoc/security-openid-connect-client-reference.adoc index 69c2fa0db1252..83ca2be79afc5 100644 --- a/docs/src/main/asciidoc/security-openid-connect-client-reference.adoc +++ b/docs/src/main/asciidoc/security-openid-connect-client-reference.adoc @@ -786,7 +786,7 @@ quarkus.oidc-client.credentials.jwt.key-file=privateKey.pem ---- quarkus.oidc-client.auth-server-url=http://localhost:8180/auth/realms/quarkus/ quarkus.oidc-client.client-id=quarkus-app -quarkus.oidc-client.credentials.jwt.key-store-file=keystore.jks +quarkus.oidc-client.credentials.jwt.key-store-file=keystore.pkcs12 quarkus.oidc-client.credentials.jwt.key-store-password=mypassword quarkus.oidc-client.credentials.jwt.key-password=mykeypassword diff --git a/extensions/oidc-client/deployment/pom.xml b/extensions/oidc-client/deployment/pom.xml index 9dd676e25f712..69e68bbdd88dd 100644 --- a/extensions/oidc-client/deployment/pom.xml +++ b/extensions/oidc-client/deployment/pom.xml @@ -93,6 +93,7 @@ true keystore.jks + keystore.pkcs12 @@ -100,6 +101,7 @@ false keystore.jks + keystore.pkcs12 diff --git a/extensions/oidc-client/deployment/src/test/java/io/quarkus/oidc/client/OidcClientCredentialsJwtPrivateP12KeyStoreTest.java b/extensions/oidc-client/deployment/src/test/java/io/quarkus/oidc/client/OidcClientCredentialsJwtPrivateP12KeyStoreTest.java new file mode 100644 index 0000000000000..29a9cb1205375 --- /dev/null +++ b/extensions/oidc-client/deployment/src/test/java/io/quarkus/oidc/client/OidcClientCredentialsJwtPrivateP12KeyStoreTest.java @@ -0,0 +1,34 @@ +package io.quarkus.oidc.client; + +import static org.hamcrest.Matchers.equalTo; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import io.quarkus.test.QuarkusUnitTest; +import io.quarkus.test.common.QuarkusTestResource; +import io.restassured.RestAssured; + +@QuarkusTestResource(KeycloakRealmClientCredentialsJwtPrivateKeyStoreManager.class) +public class OidcClientCredentialsJwtPrivateP12KeyStoreTest { + + @RegisterExtension + static final QuarkusUnitTest test = new QuarkusUnitTest() + .withApplicationRoot((jar) -> jar + .addClasses(OidcClientResource.class, ProtectedResource.class) + .addAsResource("application-oidc-client-credentials-jwt-private-p12-key-store.properties", + "application.properties") + .addAsResource("exportedCertificate.pem") + .addAsResource("exportedPrivateKey.pem") + .addAsResource("keystore.pkcs12")); + + @Test + public void testClientCredentialsToken() { + String token = RestAssured.when().get("/client/token").body().asString(); + RestAssured.given().auth().oauth2(token) + .when().get("/protected") + .then() + .statusCode(200) + .body(equalTo("service-account-quarkus-app")); + } +} diff --git a/extensions/oidc-client/deployment/src/test/resources/application-oidc-client-credentials-jwt-private-p12-key-store.properties b/extensions/oidc-client/deployment/src/test/resources/application-oidc-client-credentials-jwt-private-p12-key-store.properties new file mode 100644 index 0000000000000..6f549e1657d1a --- /dev/null +++ b/extensions/oidc-client/deployment/src/test/resources/application-oidc-client-credentials-jwt-private-p12-key-store.properties @@ -0,0 +1,9 @@ +quarkus.oidc.auth-server-url=${keycloak.url}/realms/quarkus6/ +quarkus.oidc.client-id=quarkus-app + +quarkus.oidc-client.auth-server-url=${quarkus.oidc.auth-server-url} +quarkus.oidc-client.client-id=${quarkus.oidc.client-id} +quarkus.oidc-client.credentials.jwt.key-store-file=keystore.pkcs12 +quarkus.oidc-client.credentials.jwt.key-store-password=password +quarkus.oidc-client.credentials.jwt.key-id=keycloak +quarkus.oidc-client.credentials.jwt.key-password=password diff --git a/extensions/oidc-client/deployment/src/test/resources/keystore.pkcs12 b/extensions/oidc-client/deployment/src/test/resources/keystore.pkcs12 new file mode 100755 index 0000000000000..2aa875303174e Binary files /dev/null and b/extensions/oidc-client/deployment/src/test/resources/keystore.pkcs12 differ diff --git a/extensions/oidc-common/runtime/src/main/java/io/quarkus/oidc/common/runtime/OidcCommonUtils.java b/extensions/oidc-common/runtime/src/main/java/io/quarkus/oidc/common/runtime/OidcCommonUtils.java index b97f3861427af..b74faa2e0e57c 100644 --- a/extensions/oidc-common/runtime/src/main/java/io/quarkus/oidc/common/runtime/OidcCommonUtils.java +++ b/extensions/oidc-common/runtime/src/main/java/io/quarkus/oidc/common/runtime/OidcCommonUtils.java @@ -212,7 +212,10 @@ public static String getKeyStoreType(Optional fileType, Path storePath) if (fileType.isPresent()) { return fileType.get().toUpperCase(); } - final String pathName = storePath.toString(); + return inferKeyStoreTypeFromFileExtension(storePath.toString()); + } + + private static String inferKeyStoreTypeFromFileExtension(String pathName) { if (pathName.endsWith(".p12") || pathName.endsWith(".pkcs12") || pathName.endsWith(".pfx")) { return "PKCS12"; } else { @@ -390,8 +393,9 @@ public static Key clientJwtKey(Credentials creds) { key = KeyUtils.readSigningKey(creds.jwt.getKeyFile().get(), creds.jwt.keyId.orElse(null), getSignatureAlgorithm(creds, SignatureAlgorithm.RS256)); } else if (creds.jwt.keyStoreFile.isPresent()) { - KeyStore ks = KeyStore.getInstance("JKS"); - InputStream is = ResourceUtils.getResourceStream(creds.jwt.keyStoreFile.get()); + var keyStoreFile = creds.jwt.keyStoreFile.get(); + KeyStore ks = KeyStore.getInstance(inferKeyStoreTypeFromFileExtension(keyStoreFile)); + InputStream is = ResourceUtils.getResourceStream(keyStoreFile); if (creds.jwt.keyStorePassword.isPresent()) { ks.load(is, creds.jwt.keyStorePassword.get().toCharArray());