From 1d8fae8d07b3a0228b75939f95f21e6df14f1ebb Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Tue, 12 Dec 2023 22:32:14 +0100 Subject: [PATCH 01/10] Update JReleaser descriptors for quarkus-cli to Java 17 --- devtools/cli/distribution/jreleaser-maintenance.yml | 2 +- devtools/cli/distribution/jreleaser-preview.yml | 2 +- devtools/cli/distribution/jreleaser.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/devtools/cli/distribution/jreleaser-maintenance.yml b/devtools/cli/distribution/jreleaser-maintenance.yml index e1c5e98bddc1b..15772e91a8ba7 100644 --- a/devtools/cli/distribution/jreleaser-maintenance.yml +++ b/devtools/cli/distribution/jreleaser-maintenance.yml @@ -11,7 +11,7 @@ project: java: groupId: io.quarkus artifactId: quarkus-cli - version : 11 + version : 17 tags: - cli - quarkus diff --git a/devtools/cli/distribution/jreleaser-preview.yml b/devtools/cli/distribution/jreleaser-preview.yml index 791221c4c3d1a..cbfeab135468c 100644 --- a/devtools/cli/distribution/jreleaser-preview.yml +++ b/devtools/cli/distribution/jreleaser-preview.yml @@ -11,7 +11,7 @@ project: java: groupId: io.quarkus artifactId: quarkus-cli - version : 11 + version : 17 tags: - cli - quarkus diff --git a/devtools/cli/distribution/jreleaser.yml b/devtools/cli/distribution/jreleaser.yml index b1cb13a395598..d8be28fdd50d2 100644 --- a/devtools/cli/distribution/jreleaser.yml +++ b/devtools/cli/distribution/jreleaser.yml @@ -11,7 +11,7 @@ project: java: groupId: io.quarkus artifactId: quarkus-cli - version : 11 + version : 17 tags: - cli - quarkus From d05b990c9088f2408d62f9e3bf6c9a9122acd332 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 12 Dec 2023 22:15:59 +0000 Subject: [PATCH 02/10] Bump org.eclipse.jgit:org.eclipse.jgit Bumps org.eclipse.jgit:org.eclipse.jgit from 6.7.0.202309050840-r to 6.8.0.202311291450-r. --- updated-dependencies: - dependency-name: org.eclipse.jgit:org.eclipse.jgit dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- bom/application/pom.xml | 2 +- docs/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bom/application/pom.xml b/bom/application/pom.xml index 53ded4c5d5233..19d9a972c1748 100644 --- a/bom/application/pom.xml +++ b/bom/application/pom.xml @@ -217,7 +217,7 @@ 2.7 2.4 2.4.0 - 6.7.0.202309050840-r + 6.8.0.202311291450-r 0.14.0 9.37.3 diff --git a/docs/pom.xml b/docs/pom.xml index 961a31af7f723..274c6effd891e 100644 --- a/docs/pom.xml +++ b/docs/pom.xml @@ -29,7 +29,7 @@ 2.26.0.Final 21 11.1.0 - 6.7.0.202309050840-r + 6.8.0.202311291450-r https://quarkus.io https://github.com/quarkusio/quarkus From 997b8db94969a3838f4e4973fabafcc1cf00e861 Mon Sep 17 00:00:00 2001 From: Foivos Zakkak Date: Wed, 13 Dec 2023 00:41:14 +0200 Subject: [PATCH 03/10] Remove duplicate runtime init io.netty.buffer.PooledByteBufAllocator `io.netty.buffer.PooledByteBufAllocator` is already registered for runtime initialization earlier in NettyProcessor.java Follow up to https://github.com/quarkusio/quarkus/pull/37633 Also fixes the following warning when using Mandrel and GraalVM 23.0: ``` com.oracle.svm.core.util.UserError$UserException: Incompatible change of initialization policy for io.netty.buffer.PooledByteBufAllocator: trying to change RUN_TIME from 'META-INF/native-image/io.netty/netty-buffer/native-image.properties' in 'file:///home/zakkak/code/mandrel-integration-tests/apps/jfr-native-image-performance/target/jfr-plaintext-native-image-source-jar/lib/io.netty.netty-buffer-4.1.100.Final.jar' with 'io.netty.buffer.PooledByteBufAllocator' and from feature io.quarkus.runner.Feature.beforeAnalysis with 'PooledByteBufAllocator.class' to RERUN Quarkus at org.graalvm.nativeimage.builder/com.oracle.svm.core.util.UserError.abort(UserError.java:73) at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.classinitialization.ClassInitializationConfiguration.insertRec(ClassInitializationConfiguration.java:103) at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.classinitialization.ClassInitializationConfiguration.insertRec(ClassInitializationConfiguration.java:117) at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.classinitialization.ClassInitializationConfiguration.insertRec(ClassInitializationConfiguration.java:117) at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.classinitialization.ClassInitializationConfiguration.insertRec(ClassInitializationConfiguration.java:117) at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.classinitialization.ClassInitializationConfiguration.insertRec(ClassInitializationConfiguration.java:117) at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.classinitialization.ClassInitializationConfiguration.insert(ClassInitializationConfiguration.java:64) at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.classinitialization.ProvenSafeClassInitializationSupport.rerunInitialization(ProvenSafeClassInitializationSupport.java:162) at io.quarkus.runner.Feature.runtimeReinitializedClasses(Unknown Source) at io.quarkus.runner.Feature.beforeAnalysis(Unknown Source) at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.NativeImageGenerator.lambda$runPointsToAnalysis$9(NativeImageGenerator.java:757) at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.FeatureHandler.forEachFeature(FeatureHandler.java:89) at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.NativeImageGenerator.runPointsToAnalysis(NativeImageGenerator.java:757) at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.NativeImageGenerator.doRun(NativeImageGenerator.java:582) at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.NativeImageGenerator.run(NativeImageGenerator.java:539) at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.NativeImageGeneratorRunner.buildImage(NativeImageGeneratorRunner.java:408) at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.NativeImageGeneratorRunner.build(NativeImageGeneratorRunner.java:612) at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.NativeImageGeneratorRunner.start(NativeImageGeneratorRunner.java:134) at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.NativeImageGeneratorRunner.main(NativeImageGeneratorRunner.java:94) ``` --- .../main/java/io/quarkus/netty/deployment/NettyProcessor.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/extensions/netty/deployment/src/main/java/io/quarkus/netty/deployment/NettyProcessor.java b/extensions/netty/deployment/src/main/java/io/quarkus/netty/deployment/NettyProcessor.java index 8d0f294af25fe..11801f0547d60 100644 --- a/extensions/netty/deployment/src/main/java/io/quarkus/netty/deployment/NettyProcessor.java +++ b/extensions/netty/deployment/src/main/java/io/quarkus/netty/deployment/NettyProcessor.java @@ -163,8 +163,7 @@ NativeImageConfigBuildItem build( } builder.addRuntimeReinitializedClass("io.netty.util.internal.PlatformDependent") - .addRuntimeReinitializedClass("io.netty.util.internal.PlatformDependent0") - .addRuntimeReinitializedClass("io.netty.buffer.PooledByteBufAllocator"); + .addRuntimeReinitializedClass("io.netty.util.internal.PlatformDependent0"); if (QuarkusClassLoader.isClassPresentAtRuntime("io.netty.buffer.UnpooledByteBufAllocator")) { builder.addRuntimeReinitializedClass("io.netty.buffer.UnpooledByteBufAllocator") From 3a035d586d75435726f635bc19c78c4ce467f5ab Mon Sep 17 00:00:00 2001 From: Ioannis Canellos Date: Tue, 12 Dec 2023 20:42:01 +0200 Subject: [PATCH 04/10] fix: ServiceMonitor generation (targetPort type and dekorate bump) --- bom/application/pom.xml | 2 +- .../deployment/AddServiceMonitorResourceDecorator.java | 2 +- .../it/kubernetes/KubernetesWithMetricsCustomAbsoluteTest.java | 3 ++- .../it/kubernetes/KubernetesWithMetricsCustomRelativeTest.java | 3 ++- .../it/kubernetes/KubernetesWithMetricsNoAnnotationsTest.java | 3 ++- .../io/quarkus/it/kubernetes/KubernetesWithMetricsTest.java | 3 ++- .../io/quarkus/it/kubernetes/KubernetesWithMicrometerTest.java | 3 ++- 7 files changed, 12 insertions(+), 7 deletions(-) diff --git a/bom/application/pom.xml b/bom/application/pom.xml index 53ded4c5d5233..485be398dec64 100644 --- a/bom/application/pom.xml +++ b/bom/application/pom.xml @@ -164,7 +164,7 @@ 1.7.3 0.27.0 1.6.2 - 4.1.0 + 4.1.1 3.2.0 4.2.0 3.0.2.Final diff --git a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/AddServiceMonitorResourceDecorator.java b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/AddServiceMonitorResourceDecorator.java index bc75666b48f15..425377c822541 100644 --- a/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/AddServiceMonitorResourceDecorator.java +++ b/extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/AddServiceMonitorResourceDecorator.java @@ -36,7 +36,7 @@ public void visit(KubernetesListBuilder list) { .endSelector() .addNewEndpoint() .withScheme(scheme) - .withNewTargetPort(targetPort) + .withNewTargetPort(Integer.parseInt(targetPort)) //This needs to be passed as int .withPath(path) .withInterval(interval + "s") .withHonorLabels(honorLabels) diff --git a/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithMetricsCustomAbsoluteTest.java b/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithMetricsCustomAbsoluteTest.java index 65287b49e0d01..38d59234d3081 100644 --- a/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithMetricsCustomAbsoluteTest.java +++ b/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithMetricsCustomAbsoluteTest.java @@ -92,7 +92,8 @@ public void assertGeneratedResources() throws IOException { assertThat(spec.getEndpoints()).hasSize(1); assertThat(spec.getEndpoints().get(0)).isInstanceOfSatisfying(Endpoint.class, e -> { assertThat(e.getScheme()).isEqualTo("http"); - assertThat(e.getTargetPort().getStrVal()).isEqualTo("9090"); + assertThat(e.getTargetPort().getStrVal()).isNull(); + assertThat(e.getTargetPort().getIntVal()).isEqualTo(9090); assertThat(e.getPath()).isEqualTo("/absolute-metrics"); }); }); diff --git a/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithMetricsCustomRelativeTest.java b/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithMetricsCustomRelativeTest.java index b9b9a113331ac..e12348bea4266 100644 --- a/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithMetricsCustomRelativeTest.java +++ b/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithMetricsCustomRelativeTest.java @@ -93,7 +93,8 @@ public void assertGeneratedResources() throws IOException { assertThat(spec.getEndpoints()).hasSize(1); assertThat(spec.getEndpoints().get(0)).isInstanceOfSatisfying(Endpoint.class, e -> { assertThat(e.getScheme()).isEqualTo("http"); - assertThat(e.getTargetPort().getStrVal()).isEqualTo("9090"); + assertThat(e.getTargetPort().getStrVal()).isNull(); + assertThat(e.getTargetPort().getIntVal()).isEqualTo(9090); assertThat(e.getPath()).isEqualTo("/q/met"); }); }); diff --git a/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithMetricsNoAnnotationsTest.java b/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithMetricsNoAnnotationsTest.java index aa2d0878db11e..f33973cc55fcb 100644 --- a/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithMetricsNoAnnotationsTest.java +++ b/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithMetricsNoAnnotationsTest.java @@ -92,7 +92,8 @@ public void assertGeneratedResources() throws IOException { assertThat(spec.getEndpoints()).hasSize(1); assertThat(spec.getEndpoints().get(0)).isInstanceOfSatisfying(Endpoint.class, e -> { assertThat(e.getScheme()).isEqualTo("http"); - assertThat(e.getTargetPort().getStrVal()).isEqualTo("9090"); + assertThat(e.getTargetPort().getStrVal()).isNull(); + assertThat(e.getTargetPort().getIntVal()).isEqualTo(9090); assertThat(e.getPath()).isEqualTo("/q/metrics"); }); }); diff --git a/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithMetricsTest.java b/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithMetricsTest.java index 37c51a12afcdc..f5b8d9bba4067 100644 --- a/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithMetricsTest.java +++ b/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithMetricsTest.java @@ -95,7 +95,8 @@ public void assertGeneratedResources() throws IOException { assertThat(spec.getEndpoints()).hasSize(1); assertThat(spec.getEndpoints().get(0)).isInstanceOfSatisfying(Endpoint.class, e -> { assertThat(e.getScheme()).isEqualTo("http"); - assertThat(e.getTargetPort().getStrVal()).isEqualTo("9090"); + assertThat(e.getTargetPort().getStrVal()).isNull(); + assertThat(e.getTargetPort().getIntVal()).isEqualTo(9090); assertThat(e.getPath()).isEqualTo("/q/metrics"); }); }); diff --git a/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithMicrometerTest.java b/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithMicrometerTest.java index b41e32d046c14..96b0ca8037269 100644 --- a/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithMicrometerTest.java +++ b/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithMicrometerTest.java @@ -72,7 +72,8 @@ public void assertGeneratedResources() throws IOException { assertThat(spec.getEndpoints()).hasSize(1); assertThat(spec.getEndpoints().get(0)).isInstanceOfSatisfying(Endpoint.class, e -> { assertThat(e.getScheme()).isEqualTo("http"); - assertThat(e.getTargetPort().getStrVal()).isEqualTo("8080"); + assertThat(e.getTargetPort().getStrVal()).isNull(); + assertThat(e.getTargetPort().getIntVal()).isEqualTo(8080); assertThat(e.getPath()).isEqualTo("/q/metrics"); }); }); From 7e3b81a4ba80218ec49b957bd606bf9ed2da4c69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Mathieu?= Date: Wed, 13 Dec 2023 13:54:23 +0100 Subject: [PATCH 05/10] Remove the driver property in the documentation for Cloud SQL --- docs/src/main/asciidoc/deploying-to-google-cloud.adoc | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/src/main/asciidoc/deploying-to-google-cloud.adoc b/docs/src/main/asciidoc/deploying-to-google-cloud.adoc index b63d9d2c45fad..bacfa9fb5a1ba 100644 --- a/docs/src/main/asciidoc/deploying-to-google-cloud.adoc +++ b/docs/src/main/asciidoc/deploying-to-google-cloud.adoc @@ -251,7 +251,6 @@ Finally, you need to configure your datasource specifically to use the socket fa ---- quarkus.datasource.db-kind=postgresql quarkus.datasource.jdbc.url=jdbc:postgresql:///mydatabase <1> -quarkus.datasource.jdbc.driver=org.postgresql.Driver quarkus.datasource.username=quarkus quarkus.datasource.password=quarkus quarkus.datasource.jdbc.additional-jdbc-properties.cloudSqlInstance=project-id:gcp-region:instance <2> From 72afeacb8f73efc7db27aead4675eb3c523783b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Vav=C5=99=C3=ADk?= Date: Wed, 13 Dec 2023 15:14:54 +0100 Subject: [PATCH 06/10] Docs: Fix incorrect link reference in Cross-Site Request Forgery Prevention guide --- docs/src/main/asciidoc/security-csrf-prevention.adoc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/src/main/asciidoc/security-csrf-prevention.adoc b/docs/src/main/asciidoc/security-csrf-prevention.adoc index 880487683477f..b56e7d49ad941 100644 --- a/docs/src/main/asciidoc/security-csrf-prevention.adoc +++ b/docs/src/main/asciidoc/security-csrf-prevention.adoc @@ -11,7 +11,7 @@ include::_attributes.adoc[] https://owasp.org/www-community/attacks/csrf[Cross-Site Request Forgery (CSRF)] is an attack that forces an end user to execute unwanted actions on a web application in which they are currently authenticated. -Quarkus Security provides a CSRF prevention feature which implements https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html#double-submit-cookie[Double Submit Cookie] and [CSRF Request Header] techniques. +Quarkus Security provides a CSRF prevention feature which implements https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html#double-submit-cookie[Double Submit Cookie] and <> techniques. `Double Submit Cookie` technique requires that the CSRF token sent as `HTTPOnly`, optionally signed, cookie to the client, and directly embedded in a hidden form input of server-side rendered HTML forms, or submitted as a request header value. @@ -139,6 +139,7 @@ You can get `HMAC` signatures created for the generated CSRF tokens and have the quarkus.csrf-reactive.token-signature-key=AyM1SysPpbyDfgZld3umj1qzKObwVMkoqQ-EstJQLr_T-1qS0gZH75aKtMN3Yj0iPS4hcgUuTwjAzZr1Z9CAow ---- +[[csrf-request-header]] == CSRF Request Header If HTML `form` tags are not used and you need to pass CSRF token as a header, then inject the header name and token, for example, into HTMX: From 0e4097c26f766c5b4ab1a1a646d6cd202ef96240 Mon Sep 17 00:00:00 2001 From: Sergey Beryozkin Date: Wed, 13 Dec 2023 18:18:55 +0000 Subject: [PATCH 07/10] Do not use CSRF cookie as the next token value --- .../CsrfRequestResponseReactiveFilter.java | 13 ++++---- .../java/io/quarkus/it/csrf/TestResource.java | 30 +++++++++++++++++++ .../src/main/resources/application.properties | 2 +- .../templates/csrfTokenFirstForm.html | 17 +++++++++++ .../templates/csrfTokenSecondForm.html | 17 +++++++++++ .../io/quarkus/it/csrf/CsrfReactiveTest.java | 30 +++++++++++++++++++ 6 files changed, 101 insertions(+), 8 deletions(-) create mode 100644 integration-tests/csrf-reactive/src/main/resources/templates/csrfTokenFirstForm.html create mode 100644 integration-tests/csrf-reactive/src/main/resources/templates/csrfTokenSecondForm.html diff --git a/extensions/csrf-reactive/runtime/src/main/java/io/quarkus/csrf/reactive/runtime/CsrfRequestResponseReactiveFilter.java b/extensions/csrf-reactive/runtime/src/main/java/io/quarkus/csrf/reactive/runtime/CsrfRequestResponseReactiveFilter.java index 694b690fe797f..b75764772a912 100644 --- a/extensions/csrf-reactive/runtime/src/main/java/io/quarkus/csrf/reactive/runtime/CsrfRequestResponseReactiveFilter.java +++ b/extensions/csrf-reactive/runtime/src/main/java/io/quarkus/csrf/reactive/runtime/CsrfRequestResponseReactiveFilter.java @@ -66,8 +66,6 @@ public void filter(ResteasyReactiveContainerRequestContext requestContext, Routi String cookieToken = getCookieToken(routing, config); if (cookieToken != null) { - routing.put(CSRF_TOKEN_KEY, cookieToken); - try { int cookieTokenSize = Base64.getUrlDecoder().decode(cookieToken).length; // HMAC SHA256 output is 32 bytes long @@ -98,10 +96,10 @@ public void filter(ResteasyReactiveContainerRequestContext requestContext, Routi // unsafe HTTP method, token is required // Check the header first - String csrfTokenInHeader = requestContext.getHeaderString(config.tokenHeaderName); - if (csrfTokenInHeader != null) { + String csrfTokenHeaderParam = requestContext.getHeaderString(config.tokenHeaderName); + if (csrfTokenHeaderParam != null) { LOG.debugf("CSRF token found in the token header"); - verifyCsrfToken(requestContext, routing, config, cookieToken, csrfTokenInHeader); + verifyCsrfToken(requestContext, routing, config, cookieToken, csrfTokenHeaderParam); return; } @@ -128,9 +126,9 @@ public void filter(ResteasyReactiveContainerRequestContext requestContext, Routi ResteasyReactiveRequestContext rrContext = (ResteasyReactiveRequestContext) requestContext .getServerRequestContext(); - String csrfToken = (String) rrContext.getFormParameter(config.formFieldName, true, false); + String csrfTokenFormParam = (String) rrContext.getFormParameter(config.formFieldName, true, false); LOG.debugf("CSRF token found in the form parameter"); - verifyCsrfToken(requestContext, routing, config, cookieToken, csrfToken); + verifyCsrfToken(requestContext, routing, config, cookieToken, csrfTokenFormParam); return; } else if (cookieToken == null) { @@ -159,6 +157,7 @@ private void verifyCsrfToken(ResteasyReactiveContainerRequestContext requestCont requestContext.abortWith(badClientRequest()); return; } else { + routing.put(CSRF_TOKEN_KEY, csrfToken); routing.put(CSRF_TOKEN_VERIFIED, true); return; } diff --git a/integration-tests/csrf-reactive/src/main/java/io/quarkus/it/csrf/TestResource.java b/integration-tests/csrf-reactive/src/main/java/io/quarkus/it/csrf/TestResource.java index 0f66abf3ed4a1..d3c7b18c47306 100644 --- a/integration-tests/csrf-reactive/src/main/java/io/quarkus/it/csrf/TestResource.java +++ b/integration-tests/csrf-reactive/src/main/java/io/quarkus/it/csrf/TestResource.java @@ -29,6 +29,12 @@ public class TestResource { @Inject Template csrfTokenForm; + @Inject + Template csrfTokenFirstForm; + + @Inject + Template csrfTokenSecondForm; + @Inject Template csrfTokenHeader; @@ -49,6 +55,14 @@ public TemplateInstance getCsrfTokenForm() { return csrfTokenForm.instance(); } + @GET + @Path("/csrfTokenFirstForm") + @Produces(MediaType.TEXT_HTML) + @Authenticated + public TemplateInstance getCsrfTokenFirstForm() { + return csrfTokenFirstForm.instance(); + } + @GET @Path("/csrfTokenWithFormRead") @Produces(MediaType.TEXT_HTML) @@ -71,6 +85,22 @@ public String postCsrfTokenForm(@FormParam("name") String name, @HeaderParam("X- return name + ":" + routingContext.get("csrf_token_verified", false) + ":tokenHeaderIsSet=" + (csrfHeader != null); } + @POST + @Path("/csrfTokenFirstForm") + @Consumes(MediaType.APPLICATION_FORM_URLENCODED) + @Produces(MediaType.TEXT_HTML) + public TemplateInstance postCsrfTokenFirstForm() { + return csrfTokenSecondForm.instance(); + } + + @POST + @Path("/csrfTokenSecondForm") + @Consumes(MediaType.APPLICATION_FORM_URLENCODED) + @Produces(MediaType.TEXT_PLAIN) + public String postCsrfTokenSecondForm(@FormParam("name") String name, @HeaderParam("X-CSRF-TOKEN") String csrfHeader) { + return name + ":" + routingContext.get("csrf_token_verified", false) + ":tokenHeaderIsSet=" + (csrfHeader != null); + } + @POST @Path("/csrfTokenWithFormRead") @Consumes(MediaType.APPLICATION_FORM_URLENCODED) diff --git a/integration-tests/csrf-reactive/src/main/resources/application.properties b/integration-tests/csrf-reactive/src/main/resources/application.properties index 23f5d88b8c1f0..9a778c50dda03 100644 --- a/integration-tests/csrf-reactive/src/main/resources/application.properties +++ b/integration-tests/csrf-reactive/src/main/resources/application.properties @@ -1,5 +1,5 @@ quarkus.csrf-reactive.cookie-name=csrftoken -quarkus.csrf-reactive.create-token-path=/service/csrfTokenForm,/service/csrfTokenWithFormRead,/service/csrfTokenMultipart,/service/csrfTokenWithHeader +quarkus.csrf-reactive.create-token-path=/service/csrfTokenForm,/service/csrfTokenFirstForm,/service/csrfTokenSecondForm,/service/csrfTokenWithFormRead,/service/csrfTokenMultipart,/service/csrfTokenWithHeader quarkus.csrf-reactive.token-signature-key=AyM1SysPpbyDfgZld3umj1qzKObwVMkoqQ-EstJQLr_T-1qS0gZH75aKtMN3Yj0iPS4hcgUuTwjAzZr1Z9CAow quarkus.http.auth.basic=true diff --git a/integration-tests/csrf-reactive/src/main/resources/templates/csrfTokenFirstForm.html b/integration-tests/csrf-reactive/src/main/resources/templates/csrfTokenFirstForm.html new file mode 100644 index 0000000000000..71dadecdf41e2 --- /dev/null +++ b/integration-tests/csrf-reactive/src/main/resources/templates/csrfTokenFirstForm.html @@ -0,0 +1,17 @@ + + + + +CSRF Token First Form Test + + +

CSRF Test

+ +
+ + +

Your Name:

+

+
+ + diff --git a/integration-tests/csrf-reactive/src/main/resources/templates/csrfTokenSecondForm.html b/integration-tests/csrf-reactive/src/main/resources/templates/csrfTokenSecondForm.html new file mode 100644 index 0000000000000..7c28b45f662a6 --- /dev/null +++ b/integration-tests/csrf-reactive/src/main/resources/templates/csrfTokenSecondForm.html @@ -0,0 +1,17 @@ + + + + +CSRF Token Second Form Test + + +

CSRF Test

+ +
+ + +

Your Name:

+

+
+ + diff --git a/integration-tests/csrf-reactive/src/test/java/io/quarkus/it/csrf/CsrfReactiveTest.java b/integration-tests/csrf-reactive/src/test/java/io/quarkus/it/csrf/CsrfReactiveTest.java index e6d50f0fc39b7..770d36441e300 100644 --- a/integration-tests/csrf-reactive/src/test/java/io/quarkus/it/csrf/CsrfReactiveTest.java +++ b/integration-tests/csrf-reactive/src/test/java/io/quarkus/it/csrf/CsrfReactiveTest.java @@ -61,6 +61,36 @@ public void testCsrfTokenInForm() throws Exception { } } + @Test + public void testCsrfTokenTwoForms() throws Exception { + try (final WebClient webClient = createWebClient()) { + webClient.addRequestHeader("Authorization", basicAuth("alice", "alice")); + HtmlPage htmlPage = webClient.getPage("http://localhost:8081/service/csrfTokenFirstForm"); + + assertEquals("CSRF Token First Form Test", htmlPage.getTitleText()); + + HtmlForm loginForm = htmlPage.getForms().get(0); + + loginForm.getInputByName("name").setValueAttribute("alice"); + + assertNotNull(webClient.getCookieManager().getCookie("csrftoken")); + + htmlPage = loginForm.getInputByName("submit").click(); + + assertEquals("CSRF Token Second Form Test", htmlPage.getTitleText()); + + loginForm = htmlPage.getForms().get(0); + + loginForm.getInputByName("name").setValueAttribute("alice"); + + TextPage textPage = loginForm.getInputByName("submit").click(); + assertNotNull(webClient.getCookieManager().getCookie("csrftoken")); + assertEquals("alice:true:tokenHeaderIsSet=false", textPage.getContent()); + + webClient.getCookieManager().clearCookies(); + } + } + @Test public void testCsrfTokenWithFormRead() throws Exception { try (final WebClient webClient = createWebClient()) { From ec73211198e29b1dd8e8352b2e1c5d12d00707b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Vav=C5=99=C3=ADk?= Date: Wed, 13 Dec 2023 21:11:26 +0100 Subject: [PATCH 08/10] Docs: Remove section of OIDC Dev Svc that doesnt work in new DEV UI --- .../security-openid-connect-dev-services.adoc | 77 ------------------- 1 file changed, 77 deletions(-) diff --git a/docs/src/main/asciidoc/security-openid-connect-dev-services.adoc b/docs/src/main/asciidoc/security-openid-connect-dev-services.adoc index ef10bb79181c1..cb9888041a398 100644 --- a/docs/src/main/asciidoc/security-openid-connect-dev-services.adoc +++ b/docs/src/main/asciidoc/security-openid-connect-dev-services.adoc @@ -340,83 +340,6 @@ quarkus.oidc.devui.grant.type=password quarkus.oidc.devui.grant-options.password.audience=http://localhost:8080 ---- -== Dev Services and UI Support for other OpenID Connect Providers - -Your custom extension would need to extend `quarkus-oidc` and add the dependencies required to support your provider to the extension's `deployment` module only. - -The build step dealing with the `Dev Services` should additionally register two runtime properties into the "io.quarkus.quarkus-oidc" namespace: `oidcProviderName` (for example, `Google`) and `oidcProviderUrlBase` (for example: `mycompany.devservices-google`) for the `OpenID Connect Card` to link to the Dev UI page representing your provider, for example: - -[source,java] ----- -package io.quarkus.oidc.okta.runtime; - -import java.util.function.Supplier; - -import io.quarkus.runtime.annotations.Recorder; - -// This simple recorder is the only code which will be located in the extension's `runtime` module -@Recorder -public class OktaDevServicesRecorder { - - public Supplier getProviderName() { - return new Supplier() { - - @Override - public String get() { - return "OKTA"; - } - }; - } - - public Supplier getProviderUrlBase() { - return new Supplier() { - - @Override - public String get() { - return "io.quarkus" + "." + "quarkus-oidc-okta"; - } - }; - } -} - - -package io.quarkus.oidc.okta.deployment.devservices; - -import static io.quarkus.deployment.annotations.ExecutionTime.RUNTIME_INIT; - -import java.util.Optional; - -import io.quarkus.deployment.IsDevelopment; -import io.quarkus.deployment.annotations.BuildProducer; -import io.quarkus.deployment.annotations.BuildStep; -import io.quarkus.deployment.annotations.Consume; -import io.quarkus.deployment.annotations.Record; -import io.quarkus.deployment.builditem.RuntimeConfigSetupCompleteBuildItem; -import io.quarkus.devconsole.spi.DevConsoleRouteBuildItem; -import io.quarkus.devconsole.spi.DevConsoleRuntimeTemplateInfoBuildItem; - -public class OktaDevConsoleProcessor { - - @BuildStep(onlyIf = IsDevelopment.class) - @Record(value = RUNTIME_INIT) - public void setOidcProviderProperties(BuildProducer provider, - OktaDevServicesRecorder recorder, - Optional configProps) { - if (configProps.isPresent()) { - provider.produce(new DevConsoleRuntimeTemplateInfoBuildItem("io.quarkus", "quarkus-oidc", "oidcProviderName", - recorder.getProviderName())); - provider.produce(new DevConsoleRuntimeTemplateInfoBuildItem("io.quarkus", "quarkus-oidc", "oidcProviderUrlBase", - recorder.getProviderUrlBase())); - } - } -} - ----- - -Additionally, the extension should produce a `io.quarkus.oidc.deployment.devservices.OidcProviderBuildItem` to disable the default `Dev Services for Keycloak`, instead of the users having to type `quarkus.keycloak.devservices.enabled=false`. - -Please follow the xref:dev-ui.adoc[Dev UI] tutorial as well as check the `extensions/oidc/deployment` sources for more ideas. - == Non Application Root Path Considerations This document refers to the `http://localhost:8080/q/dev-ui` Dev UI URL in several places where `q` is a default non application root path. If you customize `quarkus.http.root-path` and/or `quarkus.http.non-application-root-path` properties then replace `q` accordingly, please see https://quarkus.io/blog/path-resolution-in-quarkus/[Path Resolution in Quarkus] for more information. From a7d39b0341e3fda56fd594836a303eac864f8920 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 13 Dec 2023 23:54:00 +0000 Subject: [PATCH 09/10] Bump github/codeql-action from 2 to 3 Bumps [github/codeql-action](https://github.com/github/codeql-action) from 2 to 3. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/v2...v3) --- updated-dependencies: - dependency-name: github/codeql-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/codeql-analysis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 2f7c5e36cda32..4e2897e0d4f35 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -39,7 +39,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v2 + uses: github/codeql-action/init@v3 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -55,4 +55,4 @@ jobs: run: ./mvnw -B --settings .github/mvn-settings.xml -Dquickly-ci install - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 + uses: github/codeql-action/analyze@v3 From 2354f69f7ebc91fa16038eee70b6674a939886b7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 13 Dec 2023 23:54:06 +0000 Subject: [PATCH 10/10] Bump dawidd6/action-download-artifact from 2 to 3 Bumps [dawidd6/action-download-artifact](https://github.com/dawidd6/action-download-artifact) from 2 to 3. - [Release notes](https://github.com/dawidd6/action-download-artifact/releases) - [Commits](https://github.com/dawidd6/action-download-artifact/compare/v2...v3) --- updated-dependencies: - dependency-name: dawidd6/action-download-artifact dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/preview.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml index 013c12ee1d464..f88b0c589f348 100644 --- a/.github/workflows/preview.yml +++ b/.github/workflows/preview.yml @@ -15,7 +15,7 @@ jobs: with: repository: quarkusio/quarkusio.github.io - name: Download PR Artifact - uses: dawidd6/action-download-artifact@v2 + uses: dawidd6/action-download-artifact@v3 with: workflow: ${{ github.event.workflow_run.workflow_id }} workflow_conclusion: success