From 37f3de6c6f1004e972d274d760fe213585d9a7c0 Mon Sep 17 00:00:00 2001 From: Harald Albers Date: Tue, 4 Oct 2022 15:38:53 +0200 Subject: [PATCH 1/5] Incorporate quickstart changes in security-openid-connect-client guide https://github.com/quarkusio/quarkus-quickstarts/pull/1140 renamed two classes and two fields so that the demo more clearly communicates the usage of the RequestFilters. Signed-off-by: Harald Albers (cherry picked from commit b5cbe7cdfe4ab1a29b416f6818acabc56a9707e6) --- .../security-openid-connect-client.adoc | 27 +++++++++---------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/docs/src/main/asciidoc/security-openid-connect-client.adoc b/docs/src/main/asciidoc/security-openid-connect-client.adoc index ce30f373cef37..06825c42ecb43 100644 --- a/docs/src/main/asciidoc/security-openid-connect-client.adoc +++ b/docs/src/main/asciidoc/security-openid-connect-client.adoc @@ -158,7 +158,7 @@ import io.smallrye.mutiny.Uni; @RegisterRestClient @RegisterProvider(OidcClientRequestReactiveFilter.class) @Path("/") -public interface ProtectedResourceOidcClientFilter { +public interface RestClientWithOidcClientFilter { @GET @Produces("text/plain") @@ -172,7 +172,7 @@ public interface ProtectedResourceOidcClientFilter { } ---- -where `ProtectedResourceOidcClientFilter` will depend on `OidcClientRequestReactiveFilter` to acquire and propagate the tokens and +where `RestClientWithOidcClientFilter` will depend on `OidcClientRequestReactiveFilter` to acquire and propagate the tokens and [source,java] ---- @@ -191,7 +191,7 @@ import io.smallrye.mutiny.Uni; @RegisterRestClient @RegisterProvider(AccessTokenRequestReactiveFilter.class) @Path("/") -public interface ProtectedResourceTokenPropagationFilter { +public interface RestClientWithTokenPropagationFilter { @GET @Produces("text/plain") @@ -205,9 +205,9 @@ public interface ProtectedResourceTokenPropagationFilter { } ---- -where `ProtectedResourceTokenPropagationFilter` will depend on `AccessTokenRequestReactiveFilter` to propagate the incoming, already existing tokens. +where `RestClientWithTokenPropagationFilter` will depend on `AccessTokenRequestReactiveFilter` to propagate the incoming, already existing tokens. -Note that both `ProtectedResourceOidcClientFilter` and `ProtectedResourceTokenPropagationFilter` interfaces are identical - the reason behind it is that combining `OidcClientRequestReactiveFilter` and `AccessTokenRequestReactiveFilter` on the same REST Client will cause side effects as both filters can interfere with other, for example, `OidcClientRequestReactiveFilter` may override the token propagated by `AccessTokenRequestReactiveFilter` or `AccessTokenRequestReactiveFilter` can fail if it is called when no token is available to propagate and `OidcClientRequestReactiveFilter` is expected to acquire a new token instead. +Note that both `RestClientWithOidcClientFilter` and `RestClientWithTokenPropagationFilter` interfaces are identical - the reason behind it is that combining `OidcClientRequestReactiveFilter` and `AccessTokenRequestReactiveFilter` on the same REST Client will cause side effects as both filters can interfere with other, for example, `OidcClientRequestReactiveFilter` may override the token propagated by `AccessTokenRequestReactiveFilter` or `AccessTokenRequestReactiveFilter` can fail if it is called when no token is available to propagate and `OidcClientRequestReactiveFilter` is expected to acquire a new token instead. Now let's complete creating the application with adding `FrontendResource`: @@ -219,7 +219,6 @@ import javax.inject.Inject; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.Produces; -import javax.ws.rs.WebApplicationException; import org.eclipse.microprofile.rest.client.inject.RestClient; @@ -229,38 +228,38 @@ import io.smallrye.mutiny.Uni; public class FrontendResource { @Inject @RestClient - ProtectedResourceOidcClientFilter protectedResourceOidcClientFilter; + RestClientWithOidcClientFilter restClientWithOidcClientFilter; @Inject @RestClient - ProtectedResourceTokenPropagationFilter protectedResourceTokenPropagationFilter; + RestClientWithTokenPropagationFilter restClientWithTokenPropagationFilter; @GET @Path("user-name-with-oidc-client-token") @Produces("text/plain") public Uni getUserNameWithOidcClientToken() { - return protectedResourceOidcClientFilter.getUserName(); + return restClientWithOidcClientFilter.getUserName(); } @GET @Path("admin-name-with-oidc-client-token") @Produces("text/plain") public Uni getAdminNameWithOidcClientToken() { - return protectedResourceOidcClientFilter.getAdminName(); + return restClientWithOidcClientFilter.getAdminName(); } @GET @Path("user-name-with-propagated-token") @Produces("text/plain") public Uni getUserNameWithPropagatedToken() { - return protectedResourceTokenPropagationFilter.getUserName(); + return restClientWithTokenPropagationFilter.getUserName(); } @GET @Path("admin-name-with-propagated-token") @Produces("text/plain") public Uni getAdminNameWithPropagatedToken() { - return protectedResourceTokenPropagationFilter.getAdminName(); + return restClientWithTokenPropagationFilter.getAdminName(); } } ---- @@ -324,8 +323,8 @@ quarkus.oidc-client.grant-options.password.password=alice %dev.port=8080 %test.port=8081 -org.acme.security.openid.connect.client.ProtectedResourceOidcClientFilter/mp-rest/url=http://localhost:${port}/protected -org.acme.security.openid.connect.client.ProtectedResourceTokenPropagationFilter/mp-rest/url=http://localhost:${port}/protected +org.acme.security.openid.connect.client.RestClientWithOidcClientFilter/mp-rest/url=http://localhost:${port}/protected +org.acme.security.openid.connect.client.RestClientWithTokenPropagationFilter/mp-rest/url=http://localhost:${port}/protected ---- This configuration references Keycloak which will be used by `ProtectedResource` to verify the incoming access tokens and by `OidcClient` to get the tokens for a user `alice` using a `password` grant. Both RESTClients point to `ProtectedResource`'s HTTP address. From 6dbbd2b1ba4c9f6b6004b4bd89fdea8e8133d4c3 Mon Sep 17 00:00:00 2001 From: Harald Albers Date: Tue, 4 Oct 2022 16:21:49 +0200 Subject: [PATCH 2/5] Fix more wrong endpoints in openid-connect-client guide #26372 did not catch all occurrances of the endpoints. This commit fixes the missing ones. Signed-off-by: Harald Albers (cherry picked from commit 007ea9898a0b31284121b3c171b72133f4f067b3) --- .../src/main/asciidoc/security-openid-connect-client.adoc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/src/main/asciidoc/security-openid-connect-client.adoc b/docs/src/main/asciidoc/security-openid-connect-client.adoc index 06825c42ecb43..d9f7c4fd2269a 100644 --- a/docs/src/main/asciidoc/security-openid-connect-client.adoc +++ b/docs/src/main/asciidoc/security-openid-connect-client.adoc @@ -31,7 +31,7 @@ In this example, we will build an application which consists of two JAX-RS resou * `/frontend/user-name-with-propagated-token` * `/frontend/admin-name-with-propagated-token` -`FrontendResource` will use REST Client with `OpenID Connect Client Reactive Filter` to acquire and propagate an access token to `ProtectedResource` when either `/frontend/user-name-with-oidc-client` or `/frontend/admin-name-with-oidc-client` is called. And it will use REST Client with `OpenID Connect Token Propagation Reactive Filter` to propagate the current incoming access token to `ProtectedResource` when either `/frontend/user-name-with-propagated-token` or `/frontend/admin-name-with-propagated-token` is called. +`FrontendResource` will use REST Client with `OpenID Connect Client Reactive Filter` to acquire and propagate an access token to `ProtectedResource` when either `/frontend/user-name-with-oidc-client-token` or `/frontend/admin-name-with-oidc-client-token` is called. And it will use REST Client with `OpenID Connect Token Propagation Reactive Filter` to propagate the current incoming access token to `ProtectedResource` when either `/frontend/user-name-with-propagated-token` or `/frontend/admin-name-with-propagated-token` is called. `ProtecedResource` has 2 endpoints: @@ -264,7 +264,7 @@ public class FrontendResource { } ---- -`FrontendResource` will use REST Client with `OpenID Connect Client Reactive Filter` to acquire and propagate an access token to `ProtectedResource` when either `/frontend/user-name-with-oidc-client` or `/frontend/admin-name-with-oidc-client` is called. And it will use REST Client with `OpenID Connect Token Propagation Reactive Filter` to propagate the current incoming access token to `ProtectedResource` when either `/frontend/user-name-with-propagated-token` or `/frontend/admin-name-with-propagated-token` is called. +`FrontendResource` will use REST Client with `OpenID Connect Client Reactive Filter` to acquire and propagate an access token to `ProtectedResource` when either `/frontend/user-name-with-oidc-client-token` or `/frontend/admin-name-with-oidc-client-token` is called. And it will use REST Client with `OpenID Connect Token Propagation Reactive Filter` to propagate the current incoming access token to `ProtectedResource` when either `/frontend/user-name-with-propagated-token` or `/frontend/admin-name-with-propagated-token` is called. Finally, lets add a JAX-RS `ExceptionMapper`: @@ -485,7 +485,7 @@ Now lets check `FrontendResource` methods which do not propagate the existing to [source,bash] ---- curl -v -X GET \ - http://localhost:8080/frontend/user-name-with-oidc-client` + http://localhost:8080/frontend/user-name-with-oidc-client-token` ---- will return `200` status code and the name `alice`, but @@ -493,7 +493,7 @@ will return `200` status code and the name `alice`, but [source,bash] ---- curl -v -X GET \ - http://localhost:8080/frontend/admin-name-with-oidc-client` + http://localhost:8080/frontend/admin-name-with-oidc-client-token` ---- will return `403` status code. From 165c1ae552e541d73506e10fd938049be07e7995 Mon Sep 17 00:00:00 2001 From: Harald Albers Date: Tue, 4 Oct 2022 16:24:19 +0200 Subject: [PATCH 3/5] Minor improvements in security-openid-connect-client guide Signed-off-by: Harald Albers (cherry picked from commit fe6108446fd5d6de73225c25975f1c6133d5922a) --- .../security-openid-connect-client.adoc | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/docs/src/main/asciidoc/security-openid-connect-client.adoc b/docs/src/main/asciidoc/security-openid-connect-client.adoc index d9f7c4fd2269a..238d75d9ae6aa 100644 --- a/docs/src/main/asciidoc/security-openid-connect-client.adoc +++ b/docs/src/main/asciidoc/security-openid-connect-client.adoc @@ -139,7 +139,7 @@ public class ProtectedResource { As you can see `ProtectedResource` returns a name from both `userName()` and `adminName()` methods. The name is extracted from the current `JsonWebToken`. -Next lets add REST Client with `OpenID Connect Client Reactive Filter` and another REST Client with `OpenID Connect Token Propagation Filter`, `FrontendResource` will use these two clients to call `ProtectedResource`: +Next let's add a REST Client with `OpenID Connect Client Reactive Filter` and another REST Client with `OpenID Connect Token Propagation Filter`. `FrontendResource` will use these two clients to call `ProtectedResource`: [source,java] ---- @@ -266,7 +266,7 @@ public class FrontendResource { `FrontendResource` will use REST Client with `OpenID Connect Client Reactive Filter` to acquire and propagate an access token to `ProtectedResource` when either `/frontend/user-name-with-oidc-client-token` or `/frontend/admin-name-with-oidc-client-token` is called. And it will use REST Client with `OpenID Connect Token Propagation Reactive Filter` to propagate the current incoming access token to `ProtectedResource` when either `/frontend/user-name-with-propagated-token` or `/frontend/admin-name-with-propagated-token` is called. -Finally, lets add a JAX-RS `ExceptionMapper`: +Finally, let's add a JAX-RS `ExceptionMapper`: [source,java] ---- @@ -431,8 +431,8 @@ Now use this token to call `/frontend/user-name-with-propagated-token` and `/fro [source,bash] ---- -curl -v -X GET \ - http://localhost:8080/frontend/user-name-with-propagated-token` \ +curl -i -X GET \ + http://localhost:8080/frontend/user-name-with-propagated-token \ -H "Authorization: Bearer "$access_token ---- @@ -440,8 +440,8 @@ will return `200` status code and the name `alice` while [source,bash] ---- -curl -v -X GET \ - http://localhost:8080/frontend/admin-name-with-propagated-token` \ +curl -i -X GET \ + http://localhost:8080/frontend/admin-name-with-propagated-token \ -H "Authorization: Bearer "$access_token ---- @@ -463,8 +463,8 @@ and use this token to call `/frontend/user-name-with-propagated-token` and `/fro [source,bash] ---- -curl -v -X GET \ - http://localhost:8080/frontend/user-name-with-propagated-token` \ +curl -i -X GET \ + http://localhost:8080/frontend/user-name-with-propagated-token \ -H "Authorization: Bearer "$access_token ---- @@ -472,28 +472,28 @@ will return `200` status code and the name `admin`, and [source,bash] ---- -curl -v -X GET \ - http://localhost:8080/frontend/admin-name-with-propagated-token` \ +curl -i -X GET \ + http://localhost:8080/frontend/admin-name-with-propagated-token \ -H "Authorization: Bearer "$access_token ---- will also return `200` status code and the name `admin`, as `admin` has both `user` and `admin` roles. -Now lets check `FrontendResource` methods which do not propagate the existing tokens but use `OidcClient` to acquire and propagate the tokens. You have seen that `OidcClient` is configured to acquire the tokens for the `alice` user, so: +Now let's check `FrontendResource` methods which do not propagate the existing tokens but use `OidcClient` to acquire and propagate the tokens. You have seen that `OidcClient` is configured to acquire the tokens for the `alice` user, so: [source,bash] ---- -curl -v -X GET \ - http://localhost:8080/frontend/user-name-with-oidc-client-token` +curl -i -X GET \ + http://localhost:8080/frontend/user-name-with-oidc-client-token ---- will return `200` status code and the name `alice`, but [source,bash] ---- -curl -v -X GET \ - http://localhost:8080/frontend/admin-name-with-oidc-client-token` +curl -i -X GET \ + http://localhost:8080/frontend/admin-name-with-oidc-client-token ---- will return `403` status code. From d57a215665175711a55ef566423a58bb226adda1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yoann=20Rodi=C3=A8re?= Date: Tue, 4 Oct 2022 16:25:21 +0200 Subject: [PATCH 4/5] Fix ConfigDescriptionsManager misinterpreting a double-quote alone (`"`) as a quoted part (cherry picked from commit a034d9f3e1914fa984f33cc0b3c65e7ca95f3c00) --- .../vertx/http/runtime/devmode/ConfigDescriptionsManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/devmode/ConfigDescriptionsManager.java b/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/devmode/ConfigDescriptionsManager.java index 697bdf4274f3e..98becec8c3602 100644 --- a/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/devmode/ConfigDescriptionsManager.java +++ b/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/devmode/ConfigDescriptionsManager.java @@ -297,7 +297,7 @@ private String ensureQuoted(String part) { } private boolean isQuoted(String part) { - return part.charAt(0) == '\"' && part.charAt(part.length() - 1) == '\"'; + return part.length() >= 2 && part.charAt(0) == '\"' && part.charAt(part.length() - 1) == '\"'; } @Override From 7c8ff26b8fe22a5bed2cfde6efde1dd0aea9630a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yoann=20Rodi=C3=A8re?= Date: Tue, 4 Oct 2022 16:21:47 +0200 Subject: [PATCH 5/5] Test properties containing a double-quote alone with q/dev/io.quarkus.quarkus-vertx-http/config In particular the environment variable `__INTELLIJ_COMMAND_HISTFILE__`, translated to `%.intellij.command.histfile.`, seems to be giving that page a hard time. (cherry picked from commit a301634907907d91a4e48b4074d0b85cfb4475fd) --- ...figMisinterpretedDoubleUnderscoreTest.java | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 extensions/vertx-http/deployment/src/test/java/io/quarkus/vertx/http/devconsole/DevConsoleConfigMisinterpretedDoubleUnderscoreTest.java diff --git a/extensions/vertx-http/deployment/src/test/java/io/quarkus/vertx/http/devconsole/DevConsoleConfigMisinterpretedDoubleUnderscoreTest.java b/extensions/vertx-http/deployment/src/test/java/io/quarkus/vertx/http/devconsole/DevConsoleConfigMisinterpretedDoubleUnderscoreTest.java new file mode 100644 index 0000000000000..519d8d758578a --- /dev/null +++ b/extensions/vertx-http/deployment/src/test/java/io/quarkus/vertx/http/devconsole/DevConsoleConfigMisinterpretedDoubleUnderscoreTest.java @@ -0,0 +1,32 @@ +package io.quarkus.vertx.http.devconsole; + +import org.hamcrest.Matchers; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import io.quarkus.test.QuarkusDevModeTest; +import io.restassured.RestAssured; + +/** + * Tests that a system property such as {@code %.intellij.command.histfile."} + * doesn't lead to an exception because {@code "} is incorrectly seen as a quoted property. + *

+ * Originally the bug stemmed from an environment property {@code __INTELLIJ_COMMAND_HISTFILE__} + * which was (weirdly) interpreted as {@code %.intellij.command.histfile."}, + * but it's much easier to test system properties (which are mutable) + * than environment properties. + */ +public class DevConsoleConfigMisinterpretedDoubleUnderscoreTest { + + @RegisterExtension + static final QuarkusDevModeTest config = new QuarkusDevModeTest() + .setBuildSystemProperty("%.intellij.command.histfile.\"", "foo") + .withEmptyApplication(); + + @Test + public void testNoFailure() { + RestAssured.get("q/dev/io.quarkus.quarkus-vertx-http/config") + .then() + .statusCode(200).body(Matchers.containsString("Config Editor")); + } +}