From ff4880b8d78abbfa3543dd9ca946a324da81d1ba Mon Sep 17 00:00:00 2001 From: Sergey Beryozkin Date: Fri, 21 Jan 2022 19:50:52 +0000 Subject: [PATCH] Support OIDC Mutual TLS --- build-parent/pom.xml | 5 +- .../security-openid-connect-client.adoc | 25 +++ ...ity-openid-connect-web-authentication.adoc | 26 ++- .../oidc/common/runtime/OidcCommonConfig.java | 40 ++++ .../oidc/common/runtime/OidcCommonUtils.java | 32 ++- integration-tests/oidc/pom.xml | 16 +- .../src/main/resources/application.properties | 14 +- .../src/main/resources/client-keystore.jks | Bin 0 -> 2214 bytes .../src/main/resources/client-truststore.jks | Bin 0 -> 925 bytes .../oidc/src/main/resources/keycloak.jks | Bin 2597 -> 0 bytes .../src/main/resources/server-keystore.jks | Bin 0 -> 2215 bytes .../src/main/resources/server-truststore.jks | Bin 0 -> 925 bytes .../oidc/src/main/resources/tls.crt | Bin 891 -> 0 bytes .../oidc/src/main/resources/tls.key | 32 --- .../BearerTokenAuthorizationTest.java | 7 +- ...KeycloakXTestResourceLifecycleManager.java | 191 ++++++++++++++++++ .../it/keycloak/WebsocketOidcTestCase.java | 5 +- .../KeycloakTestResourceLifecycleManager.java | 28 +-- 18 files changed, 343 insertions(+), 78 deletions(-) create mode 100644 integration-tests/oidc/src/main/resources/client-keystore.jks create mode 100644 integration-tests/oidc/src/main/resources/client-truststore.jks delete mode 100644 integration-tests/oidc/src/main/resources/keycloak.jks create mode 100644 integration-tests/oidc/src/main/resources/server-keystore.jks create mode 100644 integration-tests/oidc/src/main/resources/server-truststore.jks delete mode 100644 integration-tests/oidc/src/main/resources/tls.crt delete mode 100644 integration-tests/oidc/src/main/resources/tls.key create mode 100644 integration-tests/oidc/src/test/java/io/quarkus/it/keycloak/KeycloakXTestResourceLifecycleManager.java diff --git a/build-parent/pom.xml b/build-parent/pom.xml index 8b362b9429ed1..f2aca372ad0b2 100644 --- a/build-parent/pom.xml +++ b/build-parent/pom.xml @@ -95,8 +95,9 @@ - quay.io/keycloak/keycloak:16.1.0 - + 16.1.0 + quay.io/keycloak/keycloak:${keycloak.version} + 6.0.3 2.27.2 diff --git a/docs/src/main/asciidoc/security-openid-connect-client.adoc b/docs/src/main/asciidoc/security-openid-connect-client.adoc index 43496dff798ba..ffa95d1e26aa9 100644 --- a/docs/src/main/asciidoc/security-openid-connect-client.adoc +++ b/docs/src/main/asciidoc/security-openid-connect-client.adoc @@ -635,6 +635,31 @@ quarkus.oidc-client.credentials.jwt.subject=${apple.subject} quarkus.oidc-client.credentials.jwt.issuer=${apple.issuer} ---- +==== Mutual TLS + +Some OpenID Connect Providers may require that a client is authenticated as part of the `Mutual TLS` (`MTLS`) authentication process. + +`quarkus-oidc-client` can be configured as follows to support `MTLS`: + +[source,properties] +---- +quarkus.oidc.tls.verification=certificate-validation + +# Keystore configuration +quarkus.oidc.client.tls.key-store-file=client-keystore.jks +quarkus.oidc.client.tls.key-store-password=${key-store-password} + +# Add more keystore properties if needed: +#quarkus.oidc.client.tls.key-store-alias=keyAlias +#quarkus.oidc.client.tls.key-store-alias-password=keyAliasPassword + +# Truststore configuration +quarkus.oidc.client.tls.trust-store-file=client-truststore.jks +quarkus.oidc.client.tls.trust-store-password=${trust-store-password} +# Add more truststore properties if needed: +#quarkus.oidc.client.tls.trust-store-alias=certAlias +---- + [[integration-testing-oidc-client]] === Testing diff --git a/docs/src/main/asciidoc/security-openid-connect-web-authentication.adoc b/docs/src/main/asciidoc/security-openid-connect-web-authentication.adoc index 711b65586749d..92b8adf89be69 100644 --- a/docs/src/main/asciidoc/security-openid-connect-web-authentication.adoc +++ b/docs/src/main/asciidoc/security-openid-connect-web-authentication.adoc @@ -978,7 +978,6 @@ quarkus.oidc.credentials.jwt.subject=custom-subject quarkus.oidc.credentials.jwt.issuer=custom-issuer ---- - ==== Apple POST JWT Apple OpenID Connect Provider uses a `client_secret_post` method where a secret is a JWT produced with a `private_key_jwt` authentication method but with Apple account specific issuer and subject claims. @@ -999,6 +998,31 @@ quarkus.oidc.credentials.jwt.subject=${apple.subject} quarkus.oidc.credentials.jwt.issuer=${apple.issuer} ---- +==== Mutual TLS + +Some OpenID Connect Providers may require that a client is authenticated as part of the `Mutual TLS` (`MTLS`) authentication process. + +`quarkus-oidc` can be configured as follows to support `MTLS`: + +[source,properties] +---- +quarkus.oidc.tls.verification=certificate-validation + +# Keystore configuration +quarkus.oidc.tls.key-store-file=client-keystore.jks +quarkus.oidc.tls.key-store-password=${key-store-password} + +# Add more keystore properties if needed: +#quarkus.oidc.tls.key-store-alias=keyAlias +#quarkus.oidc.tls.key-store-alias-password=keyAliasPassword + +# Truststore configuration +quarkus.oidc.tls.trust-store-file=client-truststore.jks +quarkus.oidc.tls.trust-store-password=${trust-store-password} +# Add more truststore properties if needed: +#quarkus.oidc.tls.trust-store-alias=certAlias +---- + [[integration-testing]] === Testing diff --git a/extensions/oidc-common/runtime/src/main/java/io/quarkus/oidc/common/runtime/OidcCommonConfig.java b/extensions/oidc-common/runtime/src/main/java/io/quarkus/oidc/common/runtime/OidcCommonConfig.java index 5797251f2f195..c8512c4ae35b6 100644 --- a/extensions/oidc-common/runtime/src/main/java/io/quarkus/oidc/common/runtime/OidcCommonConfig.java +++ b/extensions/oidc-common/runtime/src/main/java/io/quarkus/oidc/common/runtime/OidcCommonConfig.java @@ -426,6 +426,39 @@ public enum Verification { @ConfigItem public Optional verification = Optional.empty(); + /** + * An optional key store which holds the certificate information instead of specifying separate files. + */ + @ConfigItem + public Optional keyStoreFile = Optional.empty(); + + /** + * An optional parameter to specify type of the key store file. If not given, the type is automatically detected + * based on the file name. + */ + @ConfigItem + public Optional keyStoreFileType = Optional.empty(); + + /** + * A parameter to specify the password of the key store file. If not given, the default ("password") is used. + */ + @ConfigItem(defaultValue = "password") + public String keyStorePassword; + + /** + * An optional parameter to select a specific key in the key store. When SNI is disabled, if the key store contains + * multiple + * keys and no alias is specified, the behavior is undefined. + */ + @ConfigItem + public Optional keyStoreKeyAlias = Optional.empty(); + + /** + * An optional parameter to define the password for the key, in case it's different from {@link #keyStorePassword}. + */ + @ConfigItem + public Optional keyStoreKeyPassword = Optional.empty(); + /** * An optional trust store which holds the certificate information of the certificates to trust */ @@ -444,6 +477,13 @@ public enum Verification { @ConfigItem public Optional trustStoreCertAlias = Optional.empty(); + /** + * An optional parameter to specify type of the trust store file. If not given, the type is automatically detected + * based on the file name. + */ + @ConfigItem + public Optional trustStoreFileType = Optional.empty(); + public Optional getVerification() { return verification; } 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 faeedb3440126..e92b7881ffb38 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 @@ -130,7 +130,7 @@ public static void setHttpClientOptions(OidcCommonConfig oidcConfig, TlsConfig t .setPassword(oidcConfig.tls.getTrustStorePassword().orElse("password")) .setAlias(oidcConfig.tls.getTrustStoreCertAlias().orElse(null)) .setValue(io.vertx.core.buffer.Buffer.buffer(trustStoreData)) - .setType("JKS"); + .setType(getStoreType(oidcConfig.tls.trustStoreFileType, oidcConfig.tls.trustStoreFile.get())); options.setTrustOptions(trustStoreOptions); if (Verification.CERTIFICATE_VALIDATION == oidcConfig.tls.verification.orElse(Verification.REQUIRED)) { options.setVerifyHost(false); @@ -141,6 +141,23 @@ public static void setHttpClientOptions(OidcCommonConfig oidcConfig, TlsConfig t oidcConfig.tls.trustStoreFile.get().toString()), ex); } } + if (oidcConfig.tls.keyStoreFile.isPresent()) { + try { + byte[] keyStoreData = getFileContent(oidcConfig.tls.keyStoreFile.get()); + io.vertx.core.net.KeyStoreOptions keyStoreOptions = new KeyStoreOptions() + .setPassword(oidcConfig.tls.keyStorePassword) + .setAlias(oidcConfig.tls.keyStoreKeyAlias.orElse(null)) + .setAliasPassword(oidcConfig.tls.keyStoreKeyPassword.orElse(null)) + .setValue(io.vertx.core.buffer.Buffer.buffer(keyStoreData)) + .setType(getStoreType(oidcConfig.tls.keyStoreFileType, oidcConfig.tls.keyStoreFile.get())); + options.setKeyCertOptions(keyStoreOptions); + + } catch (IOException ex) { + throw new ConfigurationException(String.format( + "OIDC keystore file does not exist or can not be read", + oidcConfig.tls.keyStoreFile.get().toString()), ex); + } + } Optional proxyOpt = toProxyOptions(oidcConfig.getProxy()); if (proxyOpt.isPresent()) { options.setProxyOptions(proxyOpt.get()); @@ -154,6 +171,19 @@ public static void setHttpClientOptions(OidcCommonConfig oidcConfig, TlsConfig t options.setConnectTimeout((int) oidcConfig.getConnectionTimeout().toMillis()); } + private static String getStoreType(Optional fileType, Path storePath) { + if (fileType.isPresent()) { + return fileType.get().toUpperCase(); + } + final String pathName = storePath.toString(); + if (pathName.endsWith(".p12") || pathName.endsWith(".pkcs12") || pathName.endsWith(".pfx")) { + return "PKCS12"; + } else { + // assume jks + return "JKS"; + } + } + public static String getAuthServerUrl(OidcCommonConfig oidcConfig) { return removeLastPathSeparator(oidcConfig.getAuthServerUrl().get()); } diff --git a/integration-tests/oidc/pom.xml b/integration-tests/oidc/pom.xml index e4259d8420468..cfcee425cb1de 100644 --- a/integration-tests/oidc/pom.xml +++ b/integration-tests/oidc/pom.xml @@ -28,15 +28,23 @@ - io.quarkus - quarkus-test-keycloak-server + org.keycloak + keycloak-adapter-core test + + org.keycloak + keycloak-core + io.quarkus quarkus-test-security-oidc test + + org.testcontainers + testcontainers + io.quarkus quarkus-junit5 @@ -146,7 +154,7 @@ false - ${keycloak.docker.image} + ${keycloak.version} @@ -155,7 +163,7 @@ false - ${keycloak.docker.image} + ${keycloak.version} diff --git a/integration-tests/oidc/src/main/resources/application.properties b/integration-tests/oidc/src/main/resources/application.properties index 147ded03cb1c2..2dc3b881d4408 100644 --- a/integration-tests/oidc/src/main/resources/application.properties +++ b/integration-tests/oidc/src/main/resources/application.properties @@ -1,12 +1,16 @@ # Configuration file -quarkus.oidc.auth-server-url=${keycloak.url}/realms/quarkus/ +quarkus.oidc.auth-server-url=${quarkus.oidc.auth-server-url} quarkus.oidc.client-id=quarkus-service-app quarkus.oidc.credentials.secret=secret quarkus.oidc.token.principal-claim=email -quarkus.oidc.tls.verification=none -#quarkus.oidc.tls.verification=required -#quarkus.oidc.tls.trust-store-file=keycloak.jks -#quarkus.oidc.tls.trust-store-password=secret + +quarkus.oidc.tls.verification=certificate-validation +quarkus.oidc.tls.trust-store-file=client-truststore.jks +quarkus.oidc.tls.trust-store-password=password +quarkus.oidc.tls.key-store-file=client-keystore.jks +quarkus.oidc.tls.key-store-password=password +quarkus.native.additional-build-args=-H:IncludeResources=.*\\.jks + quarkus.http.cors=true quarkus.http.auth.basic=true diff --git a/integration-tests/oidc/src/main/resources/client-keystore.jks b/integration-tests/oidc/src/main/resources/client-keystore.jks new file mode 100644 index 0000000000000000000000000000000000000000..cf6d6ba454864d18322799afac37f520673193d6 GIT binary patch literal 2214 zcmcJQ`8O2&9>-_54#_?lreR2^8EGsf5m^giEKx+VWCk-tSu%>TFQG7!wawCFxDt1) z$&$558ao-vR`!gZd7gXkInO_Ee|Z1!I_G`9pY!>AzUTefU)o;+001DafPV|-e$)Fp zk-|kHUfYHU06+m)Dr65U1mjnM0U^MnAQ2!C3V=`{Y~pr7{iGM2;kEYzjSPZ7q9r%T zzQd$tc?+tj?ncxmVd`4L6BK!)Z-fwDm^`G}mK(Y2EM+!Pj`lgrsrJg@^?ZUUMf+9S zb$3jkBB_2WaIFmZdHlc<=hRDRlY5pevhC%>O-`2)l-y__$OB;n#8 zcs3**>MX{B3)};)HziYcmcvIR-dyS*V9sJum6L+Wy4gF3)lb{X?fxo-w|k2-JV*5M zW_@%NWtS@}s+4%_R$w)X$TxE4DA}-?{J?t`)drk|JW1vyxJdkF_Z}^{sLN8$dazje zb(9ug=(48*>>So`T-N)DLF-T}=5uE!{m69F0;RA-@rBpVq*(Et7lm8%ax@^KmH~=F)MVeABtWz zj_2v0zkl=<+;jI9t60&nFG$dAf-Ut$nvIWw8A}9kWGufYqegF4THNT(?%V#CefCz) zl*CL~jAo*5ZQSx)bd1gx`Yk2myuym#g%(>#WXmec0hJfOd6l}d=4!W-F7;Kc78_qJ zrYg-OUD={O*Gm?PYER)M*jqeb48_|4eFtq&-JimlkVRLn^8(%Ph zi3_(Cddo6Ut(!|VVJIc+wF@ZJiXVQY>@AF}Z@yTpB>(Z+cIfvja+>{VW8){3qHLW~L@8P<5~XEsR8n5V_&H46$yc*D zh=%X6Zj}i?ND&KumSL87kY8z{CNp~|b+92uI6vvG;CP15tQF3j5FD2x)`daP1L7aN zM*A#I>}4Cst8~th7b1j++S{u3>o=h@^ICcik!t~G#4S?rjZ24M9@}v<5>|a3nX)v* zNoq4I^xgCL$Ia)5nU@M1p$^lCrEdXc(dKJHCr1};b6H#I{O@HBsKsD;tz&Ezfnf^l zv5A+0ack_=h{X7zEXz00L;fVal)fUn5S5ZnRYr$XX=;aZc?K1KLAO`T@v?NDXBo6B zE!|IVW$vJCs_YM2BPrsnsg=904M(5IJD?dv-!nq+T1VAcVx#fp@1gW>#tSsudEWs_ z0#W;_)G2eu6Ly{f>07n*g9DDv&4bg_f)|dOF3FMbn5qEmD-GJ^!5wuW9wtd+ zD1)OT!~7tvl0hicD$@!jNQB{b(*+T!TgO5H?&%lz=K-e&cV6j*G}ufPSl65OSe>oU z2n7eGXS)@ie73kdD675O*7@efl>pAYH#;?9q+fGdFM7_{lJ6AtoBZ)uHE>A zpNaDEOFXD%Fiu!4U9uPBsE zaid(v!Lb5=F^?$3-J24MJHQQBF7k`=1O&MS`Ua8zXAs~Tt_MOc5@uTKS{|JgG49)PJpVeX*-@`I>AAb^fMS1ikLboS|1Gqsyf*dK zHG0NqbLL))x|HKP846)$q;k7%6Yh|?tK%WUWBL)4Z|~yi)2m}*HCcgKwCv@WoUo&$ zbR@7~v^HdROTJ2G)-m@GvvJokxO4`(f4f>E=6ZxA`D7TV|b!^>P3<~j#oFoJ!QMEGL70`0V7a6h(UJ2 zB3q+&A>(#yIdA#s`}xBz(vO~<*LQ{A(adfwx<=am!g*E{O9m**efmt4d1<;o?&7T2 z-4A<-Z2xFB9E*2`j<cI8JL?G`56qF7`d357#SJb>>3m5 zZ=H#Lv+59Q`XPs%cW*|zcHdloqAxePpx)#s-v#GfEiaLcc0X6@y`H-%=v#*1=Oe7K z)qW-B>_$?)l+O%qOP zY5rU~k%^g+fpM{-fxLk%FydtSSj1RFgzrhQ6sa|LY5ME@@w;|V$wlpR7jhs1(+w~X z85yJu_Xh_F$};l(IqMm5)_GpSy6dL=5m%H>zWY>H{I`CVzt}sMyehA$jr&-7PpP*z zM48ljF&z(>+8^ZC_}KfmbhqPb-)8xgH)l67pO-z~qM~p}$NWZ#hk(j5-lwf^Z+9IR zc2RuKX)N84ko-LLoWpNbiHME=d^>D69Nu<9Q%!uM)C=*$E z`%UAe|2n@mpUG}^eHO=ZUMDN|=Mhak)*TB!DV*2nlr){SFL#&7L?v}&&wkHmlGl&k z3^#C^8TY=sB=b?#=~rQg60Xlac=V9r%)_@Gyd?kf1a~&vU$Fg3$o1A5_JX^7TZ`vz kyRg-4({opScL4{{nL7JKu02z^Frzkj_mi(*L+#BK0Mrvya{vGU literal 0 HcmV?d00001 diff --git a/integration-tests/oidc/src/main/resources/keycloak.jks b/integration-tests/oidc/src/main/resources/keycloak.jks deleted file mode 100644 index f3035286e1f3256796cd94e384e971a45c17c9fd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2597 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 IX&!X?zsYvI$p8QV literal 0 HcmV?d00001 diff --git a/integration-tests/oidc/src/main/resources/server-truststore.jks b/integration-tests/oidc/src/main/resources/server-truststore.jks new file mode 100644 index 0000000000000000000000000000000000000000..8ec8e126507b61e0e602b71d9f67b3d7e3c7cae3 GIT binary patch literal 925 zcmezO_TO6u1_mY|W(3o$xs}0Ue&dE&8D>0B0 z=QXr6G&C?YG&M3ZGLI7HHL^4`0AdK2=Jq!+Dj|EBk(GhDiIJbdpox)-sfm%1VUF3s zo}9*=J}DCyv6d_>miqhX+0BER7vzr=weLB0SI~-EN4Tx;+oAX3sZu+AreC;W+rDov z-#5*V51%D8KX(20xaE+MMC5UqlCZ}&*8kY~jW=TIFRK(mcF!wJ^TT7)vd&p~1Uy)$ z`pW;@Uk~HZlKvCjci1|P$j&@8Uwi5_z2paTO5a=hS@rqWe0&n}OLbn_nKBuLad&4PoF%w@U!d89 z+LCrv&mDH_wWWUYJ`36D%^-U7h-9RXpo^<=ZFc0HX`&2UWMlL9lv%uVR}CpmJg{;8 zx_~1U?x&fU85tNCD;mff$O0oymXAe@MTGhL(rFKW9uTVSSw3Zn;O1#zMYmj$0}+^R zfPu)!z}8XzuI^>`BBZaSb80!?+r7pc#`09np_Lozt4zJ}{d+W?|#aPK1E8H9tc&p84 z9$uW3|Ks-G6^q-888qdu-^`O)?fLIsY>e9J3v8=pk6rP))@~NVdhf7^xr%i0hj$v? zKacmOG&aO636*{EblS9x!(U?iHAU{$t+Riy#c;{YELD{*se2PT}_AU?Y+Xxvefqh07{ov?f?J) literal 0 HcmV?d00001 diff --git a/integration-tests/oidc/src/main/resources/tls.crt b/integration-tests/oidc/src/main/resources/tls.crt deleted file mode 100644 index 659ff364761e1d0c766bce98a00a3948ad01f25c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 891 zcmXqLVlFpmVv1kD%*4pV#8UlHVV(gm8>d#AN85K^Mn-N{27??!0RuiZ=1>+kVfN6x z?7aN)JeUXvh6p=`2p5J3H--o^T*N?5oY%ER$g&|t^vtt);e_DHb-P(y8c|N(Qwsgj}J^x$ zRGrWMaUr+f%=xfK+TVDgeQcR|+Jjj}d+KdBm@+XlGB7SyG>|ut1*Q;LJ{B<+ksV9! z1CfzIy&!byi+0PLho`utHS>!E43n09dHQVm zR?Fzif=qK+KQ^_mKIy+{2JdT2rB_OfGi$qyW4?#-Yf9}YQ}z9$F4^b9FnuO_i`RPT zFA*1<z_` zT;Z-%6FA7;w!Nb2tI3j|TU;hf%%1p_H$#UxxV!v ------BEGIN PRIVATE KEY----- -MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCREYdYCTRamvG1 -/vFhAiknv8R95WV3GTMKIrJjHjYDTY8fx7kjX5JIy6y51emSBVW/jouhVCrfa12j -t+V9y66tkbEM8kQlhIldhuf3c4QTgEQHNd/4OGSGFmAYpvx+EfHILTD+5mArbhMA -FB3Cn5GfW8/4AdKotWsFEorZL2eqcbs+7qjO26CF0uV8Zk4F7vwhaenVKiWyUbaQ -8TtRPOXmtmUDaJvcBOTSJdmFxHYUsJOzojmDAMzJqu0M6sEOfoOzx8UGhYYPWLaz -kfpDOJ4Rua71usLjQGEOoeUD6xf6rpB4eKdlLPNPXlTa7JzwvBtPM6E/XXY3ZuCa -Mrx/PbA1AgMBAAECggEBAIOso2rXP/wVs9v8AmCJM43u1I1pkMWfy+IhSEYLf/9T -gNvZz0Q6VW9Z3/f2IEH4MbLj0f2nhhqxO5eFLfsWzACjw076/7wGJyELeLX01idV -P2pEDn0hwqyq1qLJv1k3NHz7+AMGXLhO+1QQ7kpfyDAbiBOWo/2aXf+Gqx0jmDbu -Ed+vRNmNpod5hOVHUjo2W500aFCcmtt2vMym713pVXfqNP6bQPAkO8VFJ7vdD63F -OIx85wcyTlTrCc0bitHaQouG3B56+T4Eg6OoVjMpFrjO4GCcqZAZyiN5QcwMEpZt -VkRCKGJfnIlNeES20I6/qURmhfkptHdJNRaD/v39cKkCgYEAzkDJ1BY+1EgyMHY0 -mRM6CiGzAbVOlW32cACYM3m6qYbM14iw2Gw2pbEmfTeuhUayRQgjOIyWEX7HzAiu -6OzI8lEXoow0ewW4E6duqHtqJy3rl2ZqYLUuVfPlhx+NcEH6cxYfknHGMCX4wUyU -pIf8Yf5qJ9zb38tqLE0bVDOt/18CgYEAtA7cy8z5g0YWmupgDKXB0n2D6XRDYl+z -8/+3PCJ9kJtNbwqREWkn7IvVQlMTCsKPME4wcvreoLedScMDIfLQNH+7F87Q6TC6 -/kOt8gvW/pkSVRXYujFK1O9KORUmuN1YHGD+rdX5T5ufA2DVWkX+Hc+5lXrHjlgY -/Eq2EnuWPOsCgYEAsgH0rxjr7ObKekzqpFqVsvzWs9i5E/qtwIii03pyAbIXxMVy -a7cpiuNTpqqR8vDLFw0o6LtdIYhcA9pSqzEBVTFrxpxfBvYuorfUp5CsU1gshqSb -lw+ICCLRrEctGP+4me80HH4ZYKDFCn9/omjDCAg9sl3JXmL/JXD+7zMTLt0CgYBD -KpQklgaxeHCwQyOnNCH0IgwWBt+oD6kyKL6yeO88BSLCfD+XLhHNhG/9+L1Oszr0 -uwYJrhlj/Hp47Hz7qfcOzmL9Q5Hcmuf2N0ro0o/Vk0YqZSbedcrDWavnVUOHjFH0 -7B20vO/uSU/s069iqF9dwYIqB43vRF+1pSz8AgwOFwKBgFGw8EkhByIzXpNX8Z9s -5nhC32vt2DgttcaSNCo0jqBUns3YgkKd1gLDppk66ZSU8xLP+TP7ge8DPpBEGERd -A/vrq2U515eqiOxu0RHOKp4cn57i+6lLpAqFz8hxkRBAPpeVNL4Yn6BHF/ouvPIW -yN6B3X4uVS/RCx4It50S8jlu ------END PRIVATE KEY----- diff --git a/integration-tests/oidc/src/test/java/io/quarkus/it/keycloak/BearerTokenAuthorizationTest.java b/integration-tests/oidc/src/test/java/io/quarkus/it/keycloak/BearerTokenAuthorizationTest.java index d97629c30a20c..993d3b9ac2bd5 100644 --- a/integration-tests/oidc/src/test/java/io/quarkus/it/keycloak/BearerTokenAuthorizationTest.java +++ b/integration-tests/oidc/src/test/java/io/quarkus/it/keycloak/BearerTokenAuthorizationTest.java @@ -1,7 +1,7 @@ package io.quarkus.it.keycloak; -import static io.quarkus.test.keycloak.server.KeycloakTestResourceLifecycleManager.getAccessToken; -import static io.quarkus.test.keycloak.server.KeycloakTestResourceLifecycleManager.getRefreshToken; +import static io.quarkus.it.keycloak.KeycloakXTestResourceLifecycleManager.getAccessToken; +import static io.quarkus.it.keycloak.KeycloakXTestResourceLifecycleManager.getRefreshToken; import static org.awaitility.Awaitility.await; import static org.hamcrest.Matchers.equalTo; @@ -14,14 +14,13 @@ import io.quarkus.test.common.QuarkusTestResource; import io.quarkus.test.junit.QuarkusTest; -import io.quarkus.test.keycloak.server.KeycloakTestResourceLifecycleManager; import io.restassured.RestAssured; /** * @author Pedro Igor */ @QuarkusTest -@QuarkusTestResource(KeycloakTestResourceLifecycleManager.class) +@QuarkusTestResource(KeycloakXTestResourceLifecycleManager.class) public class BearerTokenAuthorizationTest { @Test diff --git a/integration-tests/oidc/src/test/java/io/quarkus/it/keycloak/KeycloakXTestResourceLifecycleManager.java b/integration-tests/oidc/src/test/java/io/quarkus/it/keycloak/KeycloakXTestResourceLifecycleManager.java new file mode 100644 index 0000000000000..38e5901371f0d --- /dev/null +++ b/integration-tests/oidc/src/test/java/io/quarkus/it/keycloak/KeycloakXTestResourceLifecycleManager.java @@ -0,0 +1,191 @@ +package io.quarkus.it.keycloak; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.jboss.logging.Logger; +import org.keycloak.representations.AccessTokenResponse; +import org.keycloak.representations.idm.ClientRepresentation; +import org.keycloak.representations.idm.CredentialRepresentation; +import org.keycloak.representations.idm.RealmRepresentation; +import org.keycloak.representations.idm.RoleRepresentation; +import org.keycloak.representations.idm.RolesRepresentation; +import org.keycloak.representations.idm.UserRepresentation; +import org.keycloak.util.JsonSerialization; +import org.testcontainers.containers.BindMode; +import org.testcontainers.containers.GenericContainer; +import org.testcontainers.containers.wait.strategy.Wait; + +import io.quarkus.test.common.QuarkusTestResourceLifecycleManager; +import io.restassured.RestAssured; +import io.restassured.specification.RequestSpecification; + +public class KeycloakXTestResourceLifecycleManager implements QuarkusTestResourceLifecycleManager { + private static final Logger LOGGER = Logger.getLogger(KeycloakXTestResourceLifecycleManager.class); + private GenericContainer keycloak; + + private static String KEYCLOAK_SERVER_URL; + private static final String KEYCLOAK_REALM = "quarkus"; + private static final String KEYCLOAK_SERVICE_CLIENT = "quarkus-service-app"; + private static final String KEYCLOAK_VERSION = System.getProperty("keycloak.version"); + + private static String CLIENT_KEYSTORE = "client-keystore.jks"; + private static String CLIENT_TRUSTSTORE = "client-truststore.jks"; + + private static String SERVER_KEYSTORE = "server-keystore.jks"; + private static String SERVER_KEYSTORE_MOUNTED_PATH = "/etc/server-keystore.jks"; + private static String SERVER_TRUSTSTORE = "server-truststore.jks"; + private static String SERVER_TRUSTSTORE_MOUNTED_PATH = "/etc/server-truststore.jks"; + + @SuppressWarnings("resource") + @Override + public Map start() { + keycloak = new GenericContainer<>("quay.io/keycloak/keycloak-x:" + KEYCLOAK_VERSION) + .withExposedPorts(8080, 8443) + .withEnv("KEYCLOAK_ADMIN", "admin") + .withEnv("KEYCLOAK_ADMIN_PASSWORD", "admin") + .waitingFor(Wait.forLogMessage(".*Keycloak.*started.*", 1)); + + keycloak = keycloak + .withClasspathResourceMapping(SERVER_KEYSTORE, SERVER_KEYSTORE_MOUNTED_PATH, BindMode.READ_ONLY) + .withClasspathResourceMapping(SERVER_TRUSTSTORE, SERVER_TRUSTSTORE_MOUNTED_PATH, BindMode.READ_ONLY) + .withCommand("build --https-client-auth=required") + .withCommand(String.format( + "start --https-client-auth=required --hostname-strict=false --hostname-strict-https=false" + + " --https-key-store-file=%s --https-trust-store-file=%s --https-trust-store-password=password", + SERVER_KEYSTORE_MOUNTED_PATH, SERVER_TRUSTSTORE_MOUNTED_PATH)); + keycloak.start(); + LOGGER.info(keycloak.getLogs()); + + KEYCLOAK_SERVER_URL = "https://localhost:" + keycloak.getMappedPort(8443); + + RealmRepresentation realm = createRealm(KEYCLOAK_REALM); + postRealm(realm); + + return Map.of("quarkus.oidc.auth-server-url", KEYCLOAK_SERVER_URL + "/realms/" + KEYCLOAK_REALM); + } + + private static void postRealm(RealmRepresentation realm) { + try { + createRequestSpec().auth().oauth2(getAdminAccessToken()) + .contentType("application/json") + .body(JsonSerialization.writeValueAsBytes(realm)) + .when() + .post(KEYCLOAK_SERVER_URL + "/admin/realms").then() + .statusCode(201); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + private static RealmRepresentation createRealm(String name) { + RealmRepresentation realm = new RealmRepresentation(); + + realm.setRealm(name); + realm.setEnabled(true); + realm.setUsers(new ArrayList<>()); + realm.setClients(new ArrayList<>()); + realm.setAccessTokenLifespan(3); + realm.setSsoSessionMaxLifespan(3); + + RolesRepresentation roles = new RolesRepresentation(); + List realmRoles = new ArrayList<>(); + + roles.setRealm(realmRoles); + realm.setRoles(roles); + + realm.getRoles().getRealm().add(new RoleRepresentation("user", null, false)); + realm.getRoles().getRealm().add(new RoleRepresentation("admin", null, false)); + realm.getRoles().getRealm().add(new RoleRepresentation("confidential", null, false)); + + realm.getClients().add(createServiceClient(KEYCLOAK_SERVICE_CLIENT)); + + realm.getUsers().add(createUser("alice", List.of("user"))); + realm.getUsers().add(createUser("admin", List.of("user", "admin"))); + realm.getUsers().add(createUser("jdoe", List.of("user", "confidential"))); + + return realm; + } + + private static String getAdminAccessToken() { + return createRequestSpec() + .param("grant_type", "password") + .param("username", "admin") + .param("password", "admin") + .param("client_id", "admin-cli") + .when() + .post(KEYCLOAK_SERVER_URL + "/realms/master/protocol/openid-connect/token") + .as(AccessTokenResponse.class).getToken(); + } + + private static ClientRepresentation createServiceClient(String clientId) { + ClientRepresentation client = new ClientRepresentation(); + + client.setClientId(clientId); + client.setPublicClient(false); + client.setSecret("secret"); + client.setDirectAccessGrantsEnabled(true); + client.setServiceAccountsEnabled(true); + client.setEnabled(true); + + return client; + } + + private static UserRepresentation createUser(String username, List realmRoles) { + UserRepresentation user = new UserRepresentation(); + + user.setUsername(username); + user.setEnabled(true); + user.setCredentials(new ArrayList<>()); + user.setRealmRoles(realmRoles); + user.setEmail(username + "@gmail.com"); + + CredentialRepresentation credential = new CredentialRepresentation(); + + credential.setType(CredentialRepresentation.PASSWORD); + credential.setValue(username); + credential.setTemporary(false); + + user.getCredentials().add(credential); + + return user; + } + + public static String getAccessToken(String userName) { + return createRequestSpec().param("grant_type", "password") + .param("username", userName) + .param("password", userName) + .param("client_id", KEYCLOAK_SERVICE_CLIENT) + .param("client_secret", "secret") + .when() + .post(KEYCLOAK_SERVER_URL + "/realms/" + KEYCLOAK_REALM + "/protocol/openid-connect/token") + .as(AccessTokenResponse.class).getToken(); + } + + public static String getRefreshToken(String userName) { + return createRequestSpec().param("grant_type", "password") + .param("username", userName) + .param("password", userName) + .param("client_id", KEYCLOAK_SERVICE_CLIENT) + .param("client_secret", "secret") + .when() + .post(KEYCLOAK_SERVER_URL + "/realms/" + KEYCLOAK_REALM + "/protocol/openid-connect/token") + .as(AccessTokenResponse.class).getRefreshToken(); + } + + @Override + public void stop() { + createRequestSpec().auth().oauth2(getAdminAccessToken()) + .when() + .delete(KEYCLOAK_SERVER_URL + "/admin/realms/" + KEYCLOAK_REALM).then().statusCode(204); + + keycloak.stop(); + } + + private static RequestSpecification createRequestSpec() { + return RestAssured.given().trustStore(CLIENT_TRUSTSTORE, "password") + .keyStore(CLIENT_KEYSTORE, "password"); + } +} diff --git a/integration-tests/oidc/src/test/java/io/quarkus/it/keycloak/WebsocketOidcTestCase.java b/integration-tests/oidc/src/test/java/io/quarkus/it/keycloak/WebsocketOidcTestCase.java index a8397e06db357..50a993da34439 100644 --- a/integration-tests/oidc/src/test/java/io/quarkus/it/keycloak/WebsocketOidcTestCase.java +++ b/integration-tests/oidc/src/test/java/io/quarkus/it/keycloak/WebsocketOidcTestCase.java @@ -1,6 +1,6 @@ package io.quarkus.it.keycloak; -import static io.quarkus.test.keycloak.server.KeycloakTestResourceLifecycleManager.getAccessToken; +import static io.quarkus.it.keycloak.KeycloakXTestResourceLifecycleManager.getAccessToken; import java.net.URI; import java.util.concurrent.LinkedBlockingDeque; @@ -18,11 +18,10 @@ import io.quarkus.test.common.QuarkusTestResource; import io.quarkus.test.common.http.TestHTTPResource; import io.quarkus.test.junit.QuarkusTest; -import io.quarkus.test.keycloak.server.KeycloakTestResourceLifecycleManager; import io.quarkus.websockets.BearerTokenClientEndpointConfigurator; @QuarkusTest -@QuarkusTestResource(KeycloakTestResourceLifecycleManager.class) +@QuarkusTestResource(KeycloakXTestResourceLifecycleManager.class) public class WebsocketOidcTestCase { @TestHTTPResource("secured-hello") diff --git a/test-framework/keycloak-server/src/main/java/io/quarkus/test/keycloak/server/KeycloakTestResourceLifecycleManager.java b/test-framework/keycloak-server/src/main/java/io/quarkus/test/keycloak/server/KeycloakTestResourceLifecycleManager.java index dd8c8eb963c43..4b1d8b4676950 100644 --- a/test-framework/keycloak-server/src/main/java/io/quarkus/test/keycloak/server/KeycloakTestResourceLifecycleManager.java +++ b/test-framework/keycloak-server/src/main/java/io/quarkus/test/keycloak/server/KeycloakTestResourceLifecycleManager.java @@ -15,7 +15,6 @@ import org.keycloak.representations.idm.RolesRepresentation; import org.keycloak.representations.idm.UserRepresentation; import org.keycloak.util.JsonSerialization; -import org.testcontainers.containers.BindMode; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.wait.strategy.Wait; @@ -28,7 +27,6 @@ public class KeycloakTestResourceLifecycleManager implements QuarkusTestResource private GenericContainer keycloak; private static String KEYCLOAK_SERVER_URL; - private static final Boolean KEYCLOAK_TRUSTSTORE_REQUIRED = false; private static final String KEYCLOAK_REALM = System.getProperty("keycloak.realm", "quarkus"); private static final String KEYCLOAK_SERVICE_CLIENT = System.getProperty("keycloak.service.client", "quarkus-service-app"); private static final String KEYCLOAK_WEB_APP_CLIENT = System.getProperty("keycloak.web-app.client", "quarkus-web-app"); @@ -39,16 +37,8 @@ public class KeycloakTestResourceLifecycleManager implements QuarkusTestResource private static final String TOKEN_USER_ROLES = System.getProperty("keycloak.token.user-roles", "user"); private static final String TOKEN_ADMIN_ROLES = System.getProperty("keycloak.token.admin-roles", "user,admin"); - private static String KEYCLOAK_TRUSTSTORE_PATH = "keycloak.jks"; - private static String KEYCLOAK_TRUSTSTORE_SECRET = "secret"; - private static String KEYCLOAK_TLS_KEY = "tls.key"; - private static String KEYCLOAK_TLS_KEY_MOUNTED_PATH = "/etc/x509/https"; - private static String KEYCLOAK_TLS_CRT = "tls.crt"; - private static String KEYCLOAK_TLS_CRT_MOUNTED_PATH = "/etc/x509/https"; - static { - //KEYCLOAK_TRUSTSTORE_REQUIRED = Thread.currentThread().getContextClassLoader().getResource(KEYCLOAK_TLS_KEY) != null; - if (KEYCLOAK_USE_HTTPS && !KEYCLOAK_TRUSTSTORE_REQUIRED) { + if (KEYCLOAK_USE_HTTPS) { RestAssured.useRelaxedHTTPSValidation(); } } @@ -72,16 +62,6 @@ public Map start() { .withEnv("KEYCLOAK_PASSWORD", "admin") .waitingFor(Wait.forHttp("/auth").forPort(8080)); - if (KEYCLOAK_USE_HTTPS && KEYCLOAK_TRUSTSTORE_REQUIRED) { - keycloak = keycloak - .withClasspathResourceMapping(KEYCLOAK_TLS_KEY, KEYCLOAK_TLS_KEY_MOUNTED_PATH, BindMode.READ_ONLY) - .withClasspathResourceMapping(KEYCLOAK_TLS_CRT, KEYCLOAK_TLS_CRT_MOUNTED_PATH, BindMode.READ_ONLY); - //.withCopyFileToContainer(MountableFile.forClasspathResource(KEYCLOAK_TLS_KEY), - // KEYCLOAK_TLS_KEY_MOUNTED_PATH) - //.withCopyFileToContainer(MountableFile.forClasspathResource(KEYCLOAK_TLS_CRT), - // KEYCLOAK_TLS_CRT_MOUNTED_PATH); - } - keycloak.start(); if (KEYCLOAK_USE_HTTPS) { @@ -239,10 +219,6 @@ private static List getUserRoles() { } private static RequestSpecification createRequestSpec() { - RequestSpecification spec = RestAssured.given(); - if (KEYCLOAK_TRUSTSTORE_REQUIRED) { - spec = spec.trustStore(KEYCLOAK_TRUSTSTORE_PATH, KEYCLOAK_TRUSTSTORE_SECRET); - } - return spec; + return RestAssured.given(); } }