From 87859dfddbbe0318b7e079f1762a6d6a9168d1fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20=C3=89pardaud?= Date: Tue, 9 Jan 2024 15:31:41 +0100 Subject: [PATCH 01/42] Make sure we can do a GET with a CSRF token cookie and still obtain the token This is only a test to make sure we never regress on such a common use-case. This was already fixed in #37725 (cherry picked from commit 511b0c7113a4b6af63fdb4ee48369fff0056a8c9) --- .../java/io/quarkus/it/csrf/TestResource.java | 11 ++++++++ .../src/main/resources/application.properties | 2 +- .../io/quarkus/it/csrf/CsrfReactiveTest.java | 25 +++++++++++++++++++ 3 files changed, 37 insertions(+), 1 deletion(-) 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 d3c7b18c47306..a5042e0d76813 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 @@ -17,6 +17,7 @@ import org.eclipse.microprofile.config.ConfigProvider; import org.jboss.resteasy.reactive.RestForm; +import io.quarkus.csrf.reactive.runtime.CsrfTokenParameterProvider; import io.quarkus.csrf.reactive.runtime.CsrfTokenUtils; import io.quarkus.qute.Template; import io.quarkus.qute.TemplateInstance; @@ -47,6 +48,9 @@ public class TestResource { @Inject RoutingContext routingContext; + @Inject + CsrfTokenParameterProvider parameterProvider; + @GET @Path("/csrfTokenForm") @Produces(MediaType.TEXT_HTML) @@ -153,6 +157,13 @@ public String getSimpleGet() { return "hello"; } + @GET + @Path("/token") + @Produces(MediaType.TEXT_PLAIN) + public String getToken() { + return this.parameterProvider.getToken(); + } + public static class MultiPart { @RestForm File file; diff --git a/integration-tests/csrf-reactive/src/main/resources/application.properties b/integration-tests/csrf-reactive/src/main/resources/application.properties index 9a778c50dda03..5b6ecb5bea089 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/csrfTokenFirstForm,/service/csrfTokenSecondForm,/service/csrfTokenWithFormRead,/service/csrfTokenMultipart,/service/csrfTokenWithHeader +quarkus.csrf-reactive.create-token-path=/service/csrfTokenForm,/service/csrfTokenFirstForm,/service/csrfTokenSecondForm,/service/csrfTokenWithFormRead,/service/csrfTokenMultipart,/service/csrfTokenWithHeader,/service/token quarkus.csrf-reactive.token-signature-key=AyM1SysPpbyDfgZld3umj1qzKObwVMkoqQ-EstJQLr_T-1qS0gZH75aKtMN3Yj0iPS4hcgUuTwjAzZr1Z9CAow quarkus.http.auth.basic=true 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 e317f75c71eb3..3409acb530fb2 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 @@ -349,6 +349,31 @@ public void testWrongCsrfTokenWithFormRead() throws Exception { } } + @Test + public void testGetWithCsrfToken() throws Exception { + try (final WebClient webClient = createWebClient()) { + + assertNull(webClient.getCookieManager().getCookie("csrftoken")); + + TextPage htmlPage = webClient.getPage("http://localhost:8081/service/token"); + + assertNotNull(webClient.getCookieManager().getCookie("csrftoken")); + + // Can't check that it matches the cookie because it's signed + assertNotNull(htmlPage.getContent()); + + // get it again + htmlPage = webClient.getPage("http://localhost:8081/service/token"); + + assertNotNull(webClient.getCookieManager().getCookie("csrftoken")); + + // Can't check that it matches the cookie because it's signed + assertNotNull(htmlPage.getContent()); + + webClient.getCookieManager().clearCookies(); + } + } + private WebClient createWebClient() { WebClient webClient = new WebClient(); webClient.setCssErrorHandler(new SilentCssErrorHandler()); From 9e64ae41bf3454b7a3afc72c5084d6f4b4dc03eb Mon Sep 17 00:00:00 2001 From: Clement Escoffier Date: Wed, 17 Jan 2024 10:40:58 +0100 Subject: [PATCH 02/42] Make the route build item truly final (cherry picked from commit 286eeeb5692082ef8f580884b344834a66ff248c) --- .../http/deployment/spi/RouteBuildItem.java | 90 +++++++++++++------ 1 file changed, 62 insertions(+), 28 deletions(-) diff --git a/extensions/vertx-http/deployment-spi/src/main/java/io/quarkus/vertx/http/deployment/spi/RouteBuildItem.java b/extensions/vertx-http/deployment-spi/src/main/java/io/quarkus/vertx/http/deployment/spi/RouteBuildItem.java index d43538ce33c76..ba6828cdb9377 100644 --- a/extensions/vertx-http/deployment-spi/src/main/java/io/quarkus/vertx/http/deployment/spi/RouteBuildItem.java +++ b/extensions/vertx-http/deployment-spi/src/main/java/io/quarkus/vertx/http/deployment/spi/RouteBuildItem.java @@ -70,23 +70,41 @@ public enum RouteType { ABSOLUTE_ROUTE } - private RouteType typeOfRoute = RouteType.APPLICATION_ROUTE; + private final RouteType typeOfRoute; @SuppressWarnings("OptionalUsedAsFieldOrParameterType") - private OptionalInt order = OptionalInt.empty(); + private final OptionalInt order; - private String path; - private Consumer customizer; + private final String path; + private final Consumer customizer; - private boolean isManagement; + private final boolean isManagement; - private Handler handler; + private final Handler handler; - private HandlerType typeOfHandler = HandlerType.NORMAL; + private final HandlerType typeOfHandler = HandlerType.NORMAL; - private boolean displayOnNotFoundPage; - private String notFoundPageTitle; + private final boolean displayOnNotFoundPage; + private final String notFoundPageTitle; - private String routeConfigKey; + private final String routeConfigKey; + + @SuppressWarnings("OptionalUsedAsFieldOrParameterType") + public RouteBuildItem(RouteType typeOfRoute, String path, Consumer customizer, + boolean isManagement, + Handler handler, + boolean displayOnNotFoundPage, + String notFoundPageTitle, + String routeConfigKey, OptionalInt order) { + this.order = order; + this.typeOfRoute = typeOfRoute; + this.path = path; + this.handler = handler; + this.displayOnNotFoundPage = displayOnNotFoundPage; + this.notFoundPageTitle = notFoundPageTitle; + this.routeConfigKey = routeConfigKey; + this.customizer = customizer; + this.isManagement = isManagement; + } public RouteType getTypeOfRoute() { return typeOfRoute; @@ -246,13 +264,27 @@ public boolean isManagement() { */ public static class Builder { - private final RouteBuildItem item; + private final RouteType typeOfRoute; + @SuppressWarnings("OptionalUsedAsFieldOrParameterType") + private OptionalInt order = OptionalInt.empty(); + + private final String path; + private final boolean isManagement; + private Consumer customizer; + + private Handler handler; + + private HandlerType typeOfHandler = HandlerType.NORMAL; + + private boolean displayOnNotFoundPage; + private String notFoundPageTitle; + + private String routeConfigKey; private Builder(RouteType type, String path, boolean isManagement) { - item = new RouteBuildItem(); - item.typeOfRoute = type; - item.path = path; - item.isManagement = isManagement; + this.typeOfRoute = type; + this.path = path; + this.isManagement = isManagement; } /** @@ -262,7 +294,7 @@ private Builder(RouteType type, String path, boolean isManagement) { * @return the current builder */ public Builder withRouteCustomizer(Consumer customizer) { - item.customizer = customizer; + this.customizer = customizer; return this; } @@ -273,7 +305,7 @@ public Builder withRouteCustomizer(Consumer customizer) { * @return the current builder */ public Builder withOrder(int order) { - item.order = OptionalInt.of(order); + this.order = OptionalInt.of(order); return this; } @@ -284,7 +316,7 @@ public Builder withOrder(int order) { * @return the current builder */ public Builder withRequestHandler(Handler handler) { - item.handler = handler; + this.handler = handler; return this; } @@ -295,10 +327,10 @@ public Builder withRequestHandler(Handler handler) { * @return the current builder */ public Builder asBlockingRoute() { - if (item.typeOfHandler == HandlerType.FAILURE) { + if (this.typeOfHandler == HandlerType.FAILURE) { throw new IllegalArgumentException("A failure route cannot be a blocking route"); } - item.typeOfHandler = HandlerType.BLOCKING; + this.typeOfHandler = HandlerType.BLOCKING; return this; } @@ -309,10 +341,10 @@ public Builder asBlockingRoute() { * @return the current builder */ public Builder asFailureRoute() { - if (item.typeOfHandler == HandlerType.BLOCKING) { + if (this.typeOfHandler == HandlerType.BLOCKING) { throw new IllegalArgumentException("A blocking route cannot be a failure route"); } - item.typeOfHandler = HandlerType.FAILURE; + this.typeOfHandler = HandlerType.FAILURE; return this; } @@ -322,7 +354,7 @@ public Builder asFailureRoute() { * @return the current builder */ public Builder displayOnNotFoundPage() { - item.displayOnNotFoundPage = true; + this.displayOnNotFoundPage = true; return this; } @@ -333,8 +365,8 @@ public Builder displayOnNotFoundPage() { * @return the current builder */ public Builder displayOnNotFoundPage(String notFoundPageTitle) { - item.displayOnNotFoundPage = true; - item.notFoundPageTitle = notFoundPageTitle; + this.displayOnNotFoundPage = true; + this.notFoundPageTitle = notFoundPageTitle; return this; } @@ -345,7 +377,7 @@ public Builder displayOnNotFoundPage(String notFoundPageTitle) { * @return the current builder */ public Builder withRoutePathConfigKey(String attributeName) { - item.routeConfigKey = attributeName; + this.routeConfigKey = attributeName; return this; } @@ -355,11 +387,13 @@ public Builder withRoutePathConfigKey(String attributeName) { * @return the route build item */ public RouteBuildItem build() { - if (item.handler == null) { + if (this.handler == null) { throw new IllegalArgumentException("The route handler must be set"); } - return item; + return new RouteBuildItem(typeOfRoute, path, customizer, isManagement, handler, displayOnNotFoundPage, + notFoundPageTitle, + routeConfigKey, order); } } From c7a6e115f39626ea1a42a27bdfca9dde0c1c5e9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yoann=20Rodi=C3=A8re?= Date: Wed, 17 Jan 2024 13:46:05 +0100 Subject: [PATCH 03/42] Recommend quarkus.jib.jvm-additional-arguments rather than quarkus.jib.jvm-arguments in docs I think that setting quarkus.jib.jvm-arguments would lead to the default (-Djava.util.logging.manager=org.jboss.logmanager.LogManager) being replaced, which would mess with logging, so that's probably not something we want. (cherry picked from commit dacae71027fe6bbbdaffb3c2f0fe4d3c2eb7ab2b) --- docs/src/main/asciidoc/container-image.adoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/src/main/asciidoc/container-image.adoc b/docs/src/main/asciidoc/container-image.adoc index eb5e7c3ebff19..2fd411e028c52 100644 --- a/docs/src/main/asciidoc/container-image.adoc +++ b/docs/src/main/asciidoc/container-image.adoc @@ -47,14 +47,14 @@ For example, the presence of `src/main/jib/foo/bar` would result in `/foo/bar` There are cases where the built container image may need to have Java debugging conditionally enabled at runtime. -When the base image has not been changed (and therefore `ubi8/openjdk-11-runtime`, `ubi8/openjdk-17-runtime`, or `ubi8/openjdk-21-runtime` is used), then the `quarkus.jib.jvm-arguments` configuration property can be used in order to +When the base image has not been changed (and therefore `ubi8/openjdk-11-runtime`, `ubi8/openjdk-17-runtime`, or `ubi8/openjdk-21-runtime` is used), then the `quarkus.jib.jvm-additional-arguments` configuration property can be used in order to make the JVM listen on the debug port at startup. The exact configuration is: [source,properties] ---- -quarkus.jib.jvm-arguments=-agentlib:jdwp=transport=dt_socket\\,server=y\\,suspend=n\\,address=*:5005 +quarkus.jib.jvm-additional-arguments=-agentlib:jdwp=transport=dt_socket\\,server=y\\,suspend=n\\,address=*:5005 ---- Other base images might provide launch scripts that enable debugging when an environment variable is set, in which case you would set than environment variable when launching the container. From c5d69eb2b00b4f81a28a53e4fec8c0b91ea0f680 Mon Sep 17 00:00:00 2001 From: Georgios Andrianakis Date: Wed, 17 Jan 2024 10:58:30 +0200 Subject: [PATCH 04/42] Improve locales IT Hopefully this will alleviate the flakiness these tests have exhibited (cherry picked from commit b5a9b9da4051f1e53c3ee1f01ce9cf074515d0bb) --- integration-tests/locales/all/pom.xml | 21 +++++----- integration-tests/locales/app/pom.xml | 55 ++------------------------ integration-tests/locales/some/pom.xml | 20 +++++----- 3 files changed, 22 insertions(+), 74 deletions(-) diff --git a/integration-tests/locales/all/pom.xml b/integration-tests/locales/all/pom.xml index 1e7b627e295da..3515190980e59 100644 --- a/integration-tests/locales/all/pom.xml +++ b/integration-tests/locales/all/pom.xml @@ -13,11 +13,16 @@ io.quarkus - quarkus-arc + quarkus-resteasy-reactive io.quarkus - quarkus-resteasy-reactive + quarkus-hibernate-validator + + + io.quarkus + quarkus-integration-test-locales-app + ${project.version} @@ -31,17 +36,11 @@ rest-assured test - - io.quarkus - quarkus-integration-test-locales-app - 999-SNAPSHOT - compile - io.quarkus - quarkus-arc-deployment + quarkus-resteasy-reactive-deployment ${project.version} pom test @@ -52,10 +51,9 @@ - io.quarkus - quarkus-resteasy-reactive-deployment + quarkus-hibernate-validator-deployment ${project.version} pom test @@ -66,7 +64,6 @@ - diff --git a/integration-tests/locales/app/pom.xml b/integration-tests/locales/app/pom.xml index dae9bc473c177..3651cb3d06f1b 100644 --- a/integration-tests/locales/app/pom.xml +++ b/integration-tests/locales/app/pom.xml @@ -12,59 +12,12 @@ Quarkus - Integration Tests - Locales - App - io.quarkus - quarkus-arc + jakarta.ws.rs + jakarta.ws.rs-api - io.quarkus - quarkus-resteasy-reactive - - - io.quarkus - quarkus-hibernate-validator - - - - - io.quarkus - quarkus-arc-deployment - ${project.version} - pom - test - - - * - * - - - - - - io.quarkus - quarkus-resteasy-reactive-deployment - ${project.version} - pom - test - - - * - * - - - - - - io.quarkus - quarkus-hibernate-validator-deployment - ${project.version} - pom - test - - - * - * - - + io.smallrye.common + smallrye-common-constraint diff --git a/integration-tests/locales/some/pom.xml b/integration-tests/locales/some/pom.xml index 7f75f67f190c9..18f6c4e0195e0 100644 --- a/integration-tests/locales/some/pom.xml +++ b/integration-tests/locales/some/pom.xml @@ -13,11 +13,16 @@ io.quarkus - quarkus-arc + quarkus-resteasy-reactive io.quarkus - quarkus-resteasy-reactive + quarkus-hibernate-validator + + + io.quarkus + quarkus-integration-test-locales-app + ${project.version} @@ -31,17 +36,11 @@ rest-assured test - - io.quarkus - quarkus-integration-test-locales-app - 999-SNAPSHOT - compile - io.quarkus - quarkus-arc-deployment + quarkus-resteasy-reactive-deployment ${project.version} pom test @@ -52,10 +51,9 @@ - io.quarkus - quarkus-resteasy-reactive-deployment + quarkus-hibernate-validator-deployment ${project.version} pom test From add5596ce65242d4201cc3ae66d2a3886789596a Mon Sep 17 00:00:00 2001 From: Sergey Beryozkin Date: Wed, 17 Jan 2024 14:32:35 +0000 Subject: [PATCH 05/42] Document how Keycloak Admin Client and Dev Service can use the same port for testing (cherry picked from commit 3e1c89befaef778986f39d77f1334993a1708fcb) --- .../security-keycloak-admin-client.adoc | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/docs/src/main/asciidoc/security-keycloak-admin-client.adoc b/docs/src/main/asciidoc/security-keycloak-admin-client.adoc index cb774ef010718..a62d239d0a28c 100644 --- a/docs/src/main/asciidoc/security-keycloak-admin-client.adoc +++ b/docs/src/main/asciidoc/security-keycloak-admin-client.adoc @@ -195,6 +195,23 @@ quarkus.keycloak.admin-client.grant-type=CLIENT_CREDENTIALS <1> NOTE: Note that the xref:security-openid-connect-client.adoc[OidcClient] can also be used to acquire tokens. +== Testing + +The preferred approach for testing Keycloak Admin Client against Keycloak is xref:security-openid-connect-dev-services.adoc[Dev Services for Keycloak]. +`Dev Services for Keycloak` will start and initialize a test container. +Then, it will create a `quarkus` realm and a `quarkus-app` client (`secret` secret) and add `alice` (`admin` and `user` roles) and `bob` (`user` role) users, where all of these properties can be customized. + +For example, by default, a test container will be available at a randomly allocated port but you can make both Keycloak Admin Client and the container use the same port as follows: + +[source,properties] +---- +%test.quarkus.keycloak.devservices.port=${kc.admin.port.test:45180} <1> +%test.quarkus.keycloak.admin-client.server-url=http://localhost:${kc.admin.port.test:45180}/ <2> +---- + +<1> Configure the Keycloak container to listen on the `45180` port by default +<2> Configure the Keycloak Admin Client to use the same port + [[keycloak-admin-client-configuration-reference]] == Quarkus Keycloak Admin Client Configuration Reference From b9c0b4505fb6c0ed61fdf66648958b10d09ed0ef Mon Sep 17 00:00:00 2001 From: Rolfe Dlugy-Hegwer Date: Wed, 17 Jan 2024 09:09:21 -0500 Subject: [PATCH 06/42] Javadoc edits for quarkus-oidc.adoc (cherry picked from commit ad6d5e895ccac32d492449f9dbe37f1a9042f03e) --- .../oidc/common/runtime/OidcCommonConfig.java | 171 ++++----- .../keycloak/DevServicesConfig.java | 129 +++---- .../io/quarkus/oidc/OidcTenantConfig.java | 329 +++++++++--------- 3 files changed, 324 insertions(+), 305 deletions(-) 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 486b768c12024..b3c9f05ff21d4 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 @@ -14,83 +14,80 @@ public class OidcCommonConfig { /** * The base URL of the OpenID Connect (OIDC) server, for example, `https://host:port/auth`. - * OIDC discovery endpoint will be called by default by appending a '.well-known/openid-configuration' path to this URL. - * Note if you work with Keycloak OIDC server, make sure the base URL is in the following format: - * `https://host:port/realms/{realm}` where `{realm}` has to be replaced by the name of the Keycloak realm. + * Do not set this property if the public key verification ({@link #publicKey}) or certificate chain verification only + * ({@link #certificateChain}) is required. + * The OIDC discovery endpoint is called by default by appending a `.well-known/openid-configuration` path to this URL. + * For Keycloak, use `https://host:port/realms/{realm}`, replacing `{realm}` with the Keycloak realm name. */ @ConfigItem public Optional authServerUrl = Optional.empty(); /** - * Enables OIDC discovery. - * If the discovery is disabled then the OIDC endpoint URLs must be configured individually. + * Discovery of the OIDC endpoints. + * If not enabled, you must configure the OIDC endpoint URLs individually. */ @ConfigItem(defaultValueDocumentation = "true") public Optional discoveryEnabled = Optional.empty(); /** - * Relative path or absolute URL of the OIDC token endpoint which issues access and refresh tokens. + * The OIDC token endpoint that issues access and refresh tokens; + * specified as a relative path or absolute URL. + * Set if {@link #discoveryEnabled} is `false` or a discovered token endpoint path must be customized. */ @ConfigItem public Optional tokenPath = Optional.empty(); /** - * Relative path or absolute URL of the OIDC token revocation endpoint. + * The relative path or absolute URL of the OIDC token revocation endpoint. */ @ConfigItem public Optional revokePath = Optional.empty(); /** - * The client-id of the application. Each application has a client-id that is used to identify the application + * The client id of the application. Each application has a client id that is used to identify the application. + * Setting the client id is not required if {@link #applicationType} is `service` and no token introspection is required. */ @ConfigItem public Optional clientId = Optional.empty(); /** - * The maximum amount of time connecting to the currently unavailable OIDC server will be attempted for. - * The number of times the connection request will be repeated is calculated by dividing the value of this property by 2. - * For example, setting it to `20S` will allow for requesting the connection up to 10 times with a 2 seconds delay between - * the retries. - * Note this property is only effective when the initial OIDC connection is created, - * for example, when requesting a well-known OIDC configuration. - * Use the 'connection-retry-count' property to support trying to re-establish an already available connection which may - * have been - * dropped. + * The duration to attempt the initial connection to an OIDC server. + * For example, setting the duration to `20S` allows 10 retries, each 2 seconds apart. + * This property is only effective when the initial OIDC connection is created. + * For dropped connections, use the `connection-retry-count` property instead. */ @ConfigItem public Optional connectionDelay = Optional.empty(); /** - * The number of times an attempt to re-establish an already available connection will be repeated. - * Note this property is different from the `connection-delay` property, which is only effective during the initial OIDC - * connection creation. - * This property is used to try to recover an existing connection that may have been temporarily lost. - * For example, if a request to the OIDC token endpoint fails due to a connection exception, then the request will be - * retried the number of times configured by this property. + * The number of times to retry re-establishing an existing OIDC connection if it is temporarily lost. + * Different from `connection-delay`, which applies only to initial connection attempts. + * For instance, if a request to the OIDC token endpoint fails due to a connection issue, it will be retried as per this + * setting. */ @ConfigItem(defaultValue = "3") public int connectionRetryCount = 3; /** - * The amount of time after which the current OIDC connection request will time out. + * The number of seconds after which the current OIDC connection request times out. */ @ConfigItem(defaultValue = "10s") public Duration connectionTimeout = Duration.ofSeconds(10); /** - * The maximum size of the connection pool used by the WebClient + * The maximum size of the connection pool used by the WebClient. */ @ConfigItem public OptionalInt maxPoolSize = OptionalInt.empty(); /** - * Credentials which the OIDC adapter will use to authenticate to the OIDC server. + * Credentials the OIDC adapter uses to authenticate to the OIDC server. */ @ConfigItem public Credentials credentials = new Credentials(); /** - * Options to configure a proxy that OIDC adapter will use for talking with OIDC server. + * Options to configure the proxy the OIDC adapter uses to talk with the OIDC server. */ @ConfigItem public Proxy proxy = new Proxy(); @@ -105,15 +102,16 @@ public class OidcCommonConfig { public static class Credentials { /** - * Client secret which is used for a `client_secret_basic` authentication method. - * Note that a 'client-secret.value' can be used instead but both properties are mutually exclusive. + * The client secret used by the `client_secret_basic` authentication method. + * Must be set unless a secret is set in {@link #clientSecret} or {@link #jwt} client authentication is required. + * You can use `client-secret.value` instead, but both properties are mutually exclusive. */ @ConfigItem public Optional secret = Optional.empty(); /** - * Client secret which can be used for the `client_secret_basic` (default) and `client_secret_post` - * and 'client_secret_jwt' authentication methods. + * The client secret used by the `client_secret_basic` (default), `client_secret_post`, or `client_secret_jwt` + * authentication methods. * Note that a `secret.value` property can be used instead to support the `client_secret_basic` method * but both properties are mutually exclusive. */ @@ -121,7 +119,7 @@ public static class Credentials { public Secret clientSecret = new Secret(); /** - * Client JWT authentication methods + * Client JSON Web Token (JWT) authentication methods */ @ConfigItem public Jwt jwt = new Jwt(); @@ -151,7 +149,7 @@ public void setJwt(Jwt jwt) { } /** - * Supports the client authentication methods which involve sending a client secret. + * Supports the client authentication methods that involve sending a client secret. * * @see https://openid.net/specs/openid-connect-core-1_0.html#ClientAuthentication @@ -161,20 +159,21 @@ public static class Secret { public static enum Method { /** - * client_secret_basic (default): client id and secret are submitted with the HTTP Authorization Basic scheme + * `client_secret_basic` (default): The client id and secret are submitted with the HTTP Authorization Basic + * scheme. */ BASIC, /** - * client_secret_post: client id and secret are submitted as the `client_id` and `client_secret` form - * parameters. + * `client_secret_post`: The client id and secret are submitted as the `client_id` and `client_secret` + * form parameters. */ POST, /** - * client_secret_jwt: client id and generated JWT secret are submitted as the `client_id` and `client_secret` - * form - * parameters. + * `client_secret_jwt`: The client id and generated JWT secret are submitted as the `client_id` and + * `client_secret` + * form parameters. */ POST_JWT, @@ -186,19 +185,21 @@ public static enum Method { } /** - * The client secret value - it will be ignored if 'credentials.secret' is set + * The client secret value. This value is ignored if `credentials.secret` is set. + * Must be set unless a secret is set in {@link #clientSecret} or {@link #jwt} client authentication is required. */ @ConfigItem public Optional value = Optional.empty(); /** - * The Secret CredentialsProvider + * The Secret CredentialsProvider. */ @ConfigItem public Provider provider = new Provider(); /** - * Authentication method. + * The authentication method. + * If the `clientSecret.value` secret is set, this method is `basic` by default. */ @ConfigItem public Optional method = Optional.empty(); @@ -229,9 +230,8 @@ public void setSecretProvider(Provider secretProvider) { } /** - * Supports the client authentication 'client_secret_jwt' and `private_key_jwt` methods which involve sending a JWT - * token - * assertion signed with either a client secret or private key. + * Supports the client authentication `client_secret_jwt` and `private_key_jwt` methods, which involves sending a JWT + * token assertion signed with a client secret or private key. * * @see https://openid.net/specs/openid-connect-core-1_0.html#ClientAuthentication @@ -239,20 +239,20 @@ public void setSecretProvider(Provider secretProvider) { @ConfigGroup public static class Jwt { /** - * If provided, indicates that JWT is signed using a secret key + * If provided, indicates that JWT is signed using a secret key. */ @ConfigItem public Optional secret = Optional.empty(); /** - * If provided, indicates that JWT is signed using a secret key provided by Secret CredentialsProvider + * If provided, indicates that JWT is signed using a secret key provided by Secret CredentialsProvider. */ @ConfigItem public Provider secretProvider = new Provider(); /** - * If provided, indicates that JWT is signed using a private key in PEM or JWK format. You can use the - * {@link #signatureAlgorithm} property to specify the key algorithm. + * If provided, indicates that JWT is signed using a private key in PEM or JWK format. + * You can use the {@link #signatureAlgorithm} property to override the default key algorithm, `RS256`. */ @ConfigItem public Optional keyFile = Optional.empty(); @@ -270,38 +270,38 @@ public static class Jwt { public Optional keyStorePassword; /** - * The private key id/alias + * The private key id or alias. */ @ConfigItem public Optional keyId = Optional.empty(); /** - * The private key password + * The private key password. */ @ConfigItem public Optional keyPassword; /** - * JWT audience ('aud') claim value. + * The JWT audience (`aud`) claim value. * By default, the audience is set to the address of the OpenId Connect Provider's token endpoint. */ @ConfigItem public Optional audience = Optional.empty(); /** - * Key identifier of the signing key added as a JWT 'kid' header + * The key identifier of the signing key added as a JWT `kid` header. */ @ConfigItem public Optional tokenKeyId = Optional.empty(); /** - * Issuer of the signing key added as a JWT `iss` claim (default: client id) + * The issuer of the signing key added as a JWT `iss` claim. The default value is the client id. */ @ConfigItem public Optional issuer = Optional.empty(); /** - * Subject of the signing key added as a JWT 'sub' claim (default: client id) + * Subject of the signing key added as a JWT `sub` claim The default value is the client id. */ @ConfigItem public Optional subject = Optional.empty(); @@ -313,14 +313,16 @@ public static class Jwt { public Map claims = new HashMap<>(); /** - * Signature algorithm, also used for the {@link #keyFile} property. - * Supported values: RS256, RS384, RS512, PS256, PS384, PS512, ES256, ES384, ES512, HS256, HS384, HS512. + * The signature algorithm used for the {@link #keyFile} property. + * Supported values: `RS256` (default), `RS384`, `RS512`, `PS256`, `PS384`, `PS512`, `ES256`, `ES384`, `ES512`, + * `HS256`, `HS384`, `HS512`. */ @ConfigItem public Optional signatureAlgorithm = Optional.empty(); /** - * JWT life-span in seconds. It will be added to the time it was issued at to calculate the expiration time. + * The JWT lifespan in seconds. This value is added to the time at which the JWT was issued to calculate the + * expiration time. */ @ConfigItem(defaultValue = "10") public int lifespan = 10; @@ -392,13 +394,14 @@ public void setClaims(Map claims) { } /** - * CredentialsProvider which provides a client secret + * CredentialsProvider, which provides a client secret. */ @ConfigGroup public static class Provider { /** - * The CredentialsProvider name which should only be set if more than one CredentialsProvider is registered + * The CredentialsProvider name, which should only be set if more than one CredentialsProvider is + * registered */ @ConfigItem public Optional name = Optional.empty(); @@ -441,14 +444,15 @@ public enum Verification { CERTIFICATE_VALIDATION, /** - * All certificated are trusted and hostname verification is disabled. + * All certificates are trusted and hostname verification is disabled. */ NONE } /** - * Certificate validation and hostname verification, which can be one of the following {@link Verification} values. - * Default is required. + * Certificate validation and hostname verification, which can be one of the following {@link Verification} + * values. + * Default is `required`. */ @ConfigItem public Optional verification = Optional.empty(); @@ -460,68 +464,67 @@ public enum Verification { public Optional keyStoreFile = Optional.empty(); /** - * An optional parameter to specify type of the keystore file. If not given, the type is automatically detected - * based on the file name. + * The type of the keystore file. If not given, the type is automatically detected based on the file name. */ @ConfigItem public Optional keyStoreFileType = Optional.empty(); /** - * An optional parameter to specify a provider of the keystore file. If not given, the provider is automatically - * detected - * based on the keystore file type. + * The provider of the keystore file. If not given, the provider is automatically detected based on the + * keystore file type. */ @ConfigItem public Optional keyStoreProvider; /** - * A parameter to specify the password of the keystore file. If not given, the default ("password") is used. + * The password of the keystore file. If not given, the default value, `password`, is used. */ @ConfigItem public Optional keyStorePassword; /** - * An optional parameter to select a specific key in the keystore. When SNI is disabled, if the keystore contains - * multiple + * The alias of a specific key in the keystore. + * When SNI is disabled, if the keystore 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}. + * The password of the key, if it is different from the {@link #keyStorePassword}. */ @ConfigItem public Optional keyStoreKeyPassword = Optional.empty(); /** - * An optional truststore which holds the certificate information of the certificates to trust + * The truststore that holds the certificate information of the certificates to trust. */ @ConfigItem public Optional trustStoreFile = Optional.empty(); /** - * A parameter to specify the password of the truststore file. + * The password of the truststore file. */ @ConfigItem public Optional trustStorePassword = Optional.empty(); /** - * A parameter to specify the alias of the truststore certificate. + * The alias of the truststore certificate. */ @ConfigItem public Optional trustStoreCertAlias = Optional.empty(); /** - * An optional parameter to specify type of the truststore file. If not given, the type is automatically detected + * The type of the truststore file. + * If not given, the type is automatically detected * based on the file name. */ @ConfigItem public Optional trustStoreFileType = Optional.empty(); /** - * An optional parameter to specify a provider of the truststore file. If not given, the provider is automatically - * detected + * The provider of the truststore file. + * If not given, the provider is automatically detected * based on the truststore file type. */ @ConfigItem @@ -581,27 +584,27 @@ public void setTrustStoreProvider(String trustStoreProvider) { public static class Proxy { /** - * The host (name or IP address) of the Proxy.
- * Note: If OIDC adapter needs to use a Proxy to talk with OIDC server (Provider), - * then at least the "host" config item must be configured to enable the usage of a Proxy. + * The host name or IP address of the Proxy.
+ * Note: If the OIDC adapter requires a Proxy to talk with the OIDC server (Provider), + * set this value to enable the usage of a Proxy. */ @ConfigItem public Optional host = Optional.empty(); /** - * The port number of the Proxy. Default value is 80. + * The port number of the Proxy. The default value is `80`. */ @ConfigItem(defaultValue = "80") public int port = 80; /** - * The username, if Proxy needs authentication. + * The username, if the Proxy needs authentication. */ @ConfigItem public Optional username = Optional.empty(); /** - * The password, if Proxy needs authentication. + * The password, if the Proxy needs authentication. */ @ConfigItem public Optional password = Optional.empty(); diff --git a/extensions/oidc/deployment/src/main/java/io/quarkus/oidc/deployment/devservices/keycloak/DevServicesConfig.java b/extensions/oidc/deployment/src/main/java/io/quarkus/oidc/deployment/devservices/keycloak/DevServicesConfig.java index a12af4f1bd7bb..8e06b7889ffa5 100644 --- a/extensions/oidc/deployment/src/main/java/io/quarkus/oidc/deployment/devservices/keycloak/DevServicesConfig.java +++ b/extensions/oidc/deployment/src/main/java/io/quarkus/oidc/deployment/devservices/keycloak/DevServicesConfig.java @@ -14,52 +14,49 @@ public class DevServicesConfig { /** - * If DevServices has been explicitly enabled or disabled. - *

- * When DevServices is enabled Quarkus will attempt to automatically configure and start - * Keycloak when running in Dev or Test mode and when Docker is running. + * Flag to enable (default) or disable Dev Services. + * + * When enabled, Dev Services for Keycloak automatically configures and starts Keycloak in Dev or Test mode, and when Docker + * is running. */ @ConfigItem(defaultValue = "true") public boolean enabled = true; /** - * The container image name to use, for container-based DevServices providers. + * The container image name for Dev Services providers. * - * Image with a Quarkus based distribution is used by default. - * Image with a WildFly based distribution can be selected instead, for example: + * Defaults to a Quarkus-based Keycloak image. For a WildFly-based distribution, use an image like * `quay.io/keycloak/keycloak:19.0.3-legacy`. - *

- * Note Keycloak Quarkus and Keycloak WildFly images are initialized differently. - * By default, Dev Services for Keycloak will assume it is a Keycloak Quarkus image if the image version does not end with a - * '-legacy' - * string. - * Set 'quarkus.keycloak.devservices.keycloak-x-image' to override this check. + * + * Keycloak Quarkus and WildFly images are initialized differently. Dev Services for Keycloak will assume it is a Keycloak + * Quarkus image unless the image version + * ends with `-legacy`. + * Override with `quarkus.keycloak.devservices.keycloak-x-image`. */ @ConfigItem(defaultValue = "quay.io/keycloak/keycloak:23.0.3") public String imageName; /** - * If Keycloak-X image is used. + * Indicates if a Keycloak-X image is used. * - * By default, Dev Services for Keycloak will assume a Keycloak-X image is used if the image name contains a 'keycloak-x' - * string. - * Set 'quarkus.keycloak.devservices.keycloak-x-image' to override this check which may be necessary if you build custom - * Keycloak-X or Keycloak images. + * By default, the image is identified by `keycloak-x` in the image name. + * For custom images, override with `quarkus.keycloak.devservices.keycloak-x-image`. * You do not need to set this property if the default check works. */ @ConfigItem public Optional keycloakXImage; /** - * Indicates if the Keycloak container managed by Quarkus Dev Services is shared. - * When shared, Quarkus looks for running containers using label-based service discovery. - * If a matching container is found, it is used, and so a second one is not started. - * Otherwise, Dev Services for Keycloak starts a new container. - *

- * The discovery uses the {@code quarkus-dev-service-label} label. - * The value is configured using the {@code service-name} property. - *

- * Container sharing is only used in dev mode. + * Determines if the Keycloak container is shared. + * + * When shared, Quarkus uses label-based service discovery to find and reuse a running Keycloak container, so a second one + * is not started. + * Otherwise, if a matching container is not is found, a new container is started. + * + * The service discovery uses the {@code quarkus-dev-service-label} label, whose value is set by the {@code service-name} + * property. + * + * Container sharing is available only in dev mode. */ @ConfigItem(defaultValue = "true") public boolean shared; @@ -69,29 +66,38 @@ public class DevServicesConfig { * This property is used when {@code shared} is set to {@code true}. * In this case, before starting a container, Dev Services for Keycloak looks for a container with the * {@code quarkus-dev-service-keycloak} label - * set to the configured value. If found, it will use this container instead of starting a new one. Otherwise, it + * set to the configured value. If found, it uses this container instead of starting a new one. Otherwise, it * starts a new container with the {@code quarkus-dev-service-keycloak} label set to the specified value. *

* Container sharing is only used in dev mode. */ + /** + * The value of the `quarkus-dev-service-keycloak` label for identifying the Keycloak container. + * + * Used in shared mode to locate an existing container with this label. If not found, a new container is initialized with + * this label. + * + * Applicable only in dev mode. + */ @ConfigItem(defaultValue = "quarkus") public String serviceName; /** - * The comma-separated list of class or file system paths to Keycloak realm files which will be used to initialize Keycloak. - * The first value in this list will be used to initialize default tenant connection properties. + * A comma-separated list of class or file system paths to Keycloak realm files. + * This list is used to initialize Keycloak. + * The first value in this list is used to initialize default tenant connection properties. */ @ConfigItem public Optional> realmPath; /** - * Aliases to additional class or file system resources which will be used to initialize Keycloak. + * Aliases to additional class or file system resources that are used to initialize Keycloak. * Each map entry represents a mapping between an alias and a class or file system resource path. */ @ConfigItem public Map resourceAliases; /** - * Additional class or file system resources which will be used to initialize Keycloak. + * Additional class or file system resources that are used to initialize Keycloak. * Each map entry represents a mapping between a class or file system resource path alias and the Keycloak container * location. */ @@ -99,7 +105,7 @@ public class DevServicesConfig { public Map resourceMappings; /** - * The JAVA_OPTS passed to the keycloak JVM + * The `JAVA_OPTS` passed to the keycloak JVM */ @ConfigItem public Optional javaOpts; @@ -113,55 +119,54 @@ public class DevServicesConfig { /** * Keycloak start command. * Use this property to experiment with Keycloak start options, see {@link https://www.keycloak.org/server/all-config}. - * Note it will be ignored when loading legacy Keycloak WildFly images. + * Note, it is ignored when loading legacy Keycloak WildFly images. */ @ConfigItem public Optional startCommand; /** - * The Keycloak realm name. - * This property will be used to create the realm if the realm file pointed to by the `realm-path` property does not exist, - * default value is `quarkus` in this case. - * If the realm file pointed to by the `realm-path` property exists then it is still recommended to set this property - * for Dev Services for Keycloak to avoid parsing the realm file to determine the realm name. + * The name of the Keycloak realm. * + * This property is used to create the realm if the realm file pointed to by the `realm-path` property does not exist. + * The default value is `quarkus` in this case. + * It is recommended to always set this property so that Dev Services for Keycloak can identify the realm name without + * parsing the realm file. */ @ConfigItem public Optional realmName; /** - * Indicates if the Keycloak realm has to be created when the realm file pointed to by the `realm-path` property does not - * exist. + * Specifies whether to create the Keycloak realm when no realm file is found at the `realm-path`. * - * Disable it if you'd like to create a realm using Keycloak Administration Console - * or Keycloak Admin API from {@linkplain io.quarkus.test.common.QuarkusTestResourceLifecycleManager}. + * Set to `false` if the realm is to be created using either the Keycloak Administration Console or + * the Keycloak Admin API provided by {@linkplain io.quarkus.test.common.QuarkusTestResourceLifecycleManager}. */ @ConfigItem(defaultValue = "true") public boolean createRealm; /** - * The Keycloak users map containing the username and password pairs. - * If this map is empty then two users, 'alice' and 'bob' with the passwords matching their names will be created. - * This property will be used to create the Keycloak users if the realm file pointed to by the `realm-path` property does - * not exist. + * A map of Keycloak usernames to passwords. + * + * If empty, default users `alice` and `bob` are created with their names as passwords. + * This map is used for user creation when no realm file is found at the `realm-path`. */ @ConfigItem public Map users; /** - * The Keycloak user roles. - * If this map is empty then a user named 'alice' will get 'admin' and 'user' roles and all other users will get a 'user' - * role. - * This property will be used to create the Keycloak roles if the realm file pointed to by the `realm-path` property does - * not exist. + * A map of roles for Keycloak users. + * + * If empty, default roles are assigned: `alice` receives `admin` and `user` roles, while other users receive + * `user` role. + * This map is used for role creation when no realm file is found at the `realm-path`. */ @ConfigItem public Map> roles; /** - * Grant type. + * Specifies the grant type. * - * @deprecated Use {@link DevUiConfig#grant}. + * @deprecated This field is deprecated. Use {@link DevUiConfig#grant} instead. */ @Deprecated public Grant grant = new Grant(); @@ -170,21 +175,21 @@ public class DevServicesConfig { public static class Grant { public static enum Type { /** - * 'client_credentials' grant + * `client_credentials` grant */ CLIENT("client_credentials"), /** - * 'password' grant + * `password` grant */ PASSWORD("password"), /** - * 'authorization_code' grant + * `authorization_code` grant */ CODE("code"), /** - * 'implicit' grant + * `implicit` grant */ IMPLICIT("implicit"); @@ -200,22 +205,22 @@ public String getGrantType() { } /** - * Grant type which will be used to acquire a token to test the OIDC 'service' applications + * Defines the grant type for aquiring tokens for testing OIDC `service` applications. */ @ConfigItem(defaultValue = "code") public Type type = Type.CODE; } /** - * Optional fixed port the dev service will listen to. + * The specific port for the dev service to listen on. *

- * If not defined, the port will be chosen randomly. + * If not specified, a random port is selected. */ @ConfigItem public OptionalInt port; /** - * Environment variables that are passed to the container. + * Environment variables to be passed to the container. */ @ConfigItem public Map containerEnv; diff --git a/extensions/oidc/runtime/src/main/java/io/quarkus/oidc/OidcTenantConfig.java b/extensions/oidc/runtime/src/main/java/io/quarkus/oidc/OidcTenantConfig.java index 805099be88105..77cbdaa69fa9f 100644 --- a/extensions/oidc/runtime/src/main/java/io/quarkus/oidc/OidcTenantConfig.java +++ b/extensions/oidc/runtime/src/main/java/io/quarkus/oidc/OidcTenantConfig.java @@ -23,8 +23,8 @@ public class OidcTenantConfig extends OidcCommonConfig { /** - * A unique tenant identifier. It must be set by {@code TenantConfigResolver} providers which - * resolve the tenant configuration dynamically and is optional in all other cases. + * A unique tenant identifier. It can be set by {@code TenantConfigResolver} providers, which + * resolve the tenant configuration dynamically. */ @ConfigItem public Optional tenantId = Optional.empty(); @@ -32,10 +32,10 @@ public class OidcTenantConfig extends OidcCommonConfig { /** * If this tenant configuration is enabled. * - * Note that the default tenant will be disabled if it is not configured but either - * {@link TenantConfigResolver} which will resolve tenant configurations is registered + * The default tenant is disabled if it is not configured but + * a {@link TenantConfigResolver} that resolves tenant configurations is registered, * or named tenants are configured. - * You do not have to disable the default tenant in this case. + * In this case, you do not need to disable the default tenant. */ @ConfigItem(defaultValue = "true") public boolean tenantEnabled = true; @@ -47,51 +47,54 @@ public class OidcTenantConfig extends OidcCommonConfig { public Optional applicationType = Optional.empty(); /** - * Relative path or absolute URL of the OIDC authorization endpoint which authenticates the users. - * This property must be set for the 'web-app' applications if OIDC discovery is disabled. - * This property will be ignored if the discovery is enabled. + * The relative path or absolute URL of the OpenID Connect (OIDC) authorization endpoint, which authenticates + * users. + * You must set this property for `web-app` applications if OIDC discovery is disabled. + * This property is ignored if OIDC discovery is enabled. */ @ConfigItem public Optional authorizationPath = Optional.empty(); /** - * Relative path or absolute URL of the OIDC UserInfo endpoint. - * This property must only be set for the 'web-app' applications if OIDC discovery is disabled - * and `authentication.user-info-required` property is enabled. - * This property will be ignored if the discovery is enabled. + * The relative path or absolute URL of the OIDC UserInfo endpoint. + * You must set this property for `web-app` applications if OIDC discovery is disabled + * and the `authentication.user-info-required` property is enabled. + * This property is ignored if OIDC discovery is enabled. */ @ConfigItem public Optional userInfoPath = Optional.empty(); /** - * Relative path or absolute URL of the OIDC RFC7662 introspection endpoint which can introspect both opaque and JWT tokens. - * This property must be set if OIDC discovery is disabled and 1) the opaque bearer access tokens have to be verified - * or 2) JWT tokens have to be verified while the cached JWK verification set with no matching JWK is being refreshed. - * This property will be ignored if the discovery is enabled. + * Relative path or absolute URL of the OIDC RFC7662 introspection endpoint which can introspect both opaque and + * JSON Web Token (JWT) tokens. + * This property must be set if OIDC discovery is disabled and 1) the opaque bearer access tokens must be verified + * or 2) JWT tokens must be verified while the cached JWK verification set with no matching JWK is being refreshed. + * This property is ignored if the discovery is enabled. */ @ConfigItem public Optional introspectionPath = Optional.empty(); /** - * Relative path or absolute URL of the OIDC JWKS endpoint which returns a JSON Web Key Verification Set. + * Relative path or absolute URL of the OIDC JSON Web Key Set (JWKS) endpoint which returns a JSON Web Key + * Verification Set. * This property should be set if OIDC discovery is disabled and the local JWT verification is required. - * This property will be ignored if the discovery is enabled. + * This property is ignored if the discovery is enabled. */ @ConfigItem public Optional jwksPath = Optional.empty(); /** * Relative path or absolute URL of the OIDC end_session_endpoint. - * This property must be set if OIDC discovery is disabled and RP Initiated Logout support for the 'web-app' applications is + * This property must be set if OIDC discovery is disabled and RP Initiated Logout support for the `web-app` applications is * required. - * This property will be ignored if the discovery is enabled. + * This property is ignored if the discovery is enabled. */ @ConfigItem public Optional endSessionPath = Optional.empty(); /** - * Public key for the local JWT token verification. - * OIDC server connection will not be created when this property is set. + * The public key for the local JWT token verification. + * OIDC server connection is not created when this property is set. */ @ConfigItem public Optional publicKey = Optional.empty(); @@ -122,7 +125,7 @@ public static class IntrospectionCredentials { public Optional secret = Optional.empty(); /** - * Include OpenId Connect Client ID configured with 'quarkus.oidc.client-id' + * Include OpenId Connect Client ID configured with `quarkus.oidc.client-id`. */ @ConfigItem(defaultValue = "true") public boolean includeClientId = true; @@ -173,7 +176,7 @@ public void setIncludeClientId(boolean includeClientId) { /** * Configuration of the certificate chain which can be used to verify tokens. - * If the certificate chain trusstore is configured then the tokens can be verified using the certificate + * If the certificate chain trusstore is configured, the tokens can be verified using the certificate * chain inlined in the Base64-encoded format as an `x5c` header in the token itself. */ @ConfigItem @@ -182,7 +185,7 @@ public void setIncludeClientId(boolean includeClientId) { @ConfigGroup public static class CertificateChain { /** - * Truststore file which keeps thumbprints of the trusted certificates + * Truststore file which keeps thumbprints of the trusted certificates. */ @ConfigItem public Optional trustStoreFile = Optional.empty(); @@ -200,7 +203,8 @@ public static class CertificateChain { public Optional trustStoreCertAlias = Optional.empty(); /** - * An optional parameter to specify type of the truststore file. If not given, the type is automatically detected + * An optional parameter to specify type of the truststore file. If not given, the type is automatically + * detected * based on the file name. */ @ConfigItem @@ -278,14 +282,16 @@ public void setTrustStoreFileType(Optional trustStoreFileType) { public static class Logout { /** - * The relative path of the logout endpoint at the application. If provided, the application is able to initiate the + * The relative path of the logout endpoint at the application. If provided, the application is able to + * initiate the * logout through this endpoint in conformance with the OpenID Connect RP-Initiated Logout specification. */ @ConfigItem public Optional path = Optional.empty(); /** - * Relative path of the application endpoint where the user should be redirected to after logging out from the OpenID + * Relative path of the application endpoint where the user should be redirected to after logging out from the + * OpenID * Connect Provider. * This endpoint URI must be properly registered at the OpenID Connect Provider as a valid redirect URI. */ @@ -293,13 +299,13 @@ public static class Logout { public Optional postLogoutPath = Optional.empty(); /** - * Name of the post logout URI parameter which will be added as a query parameter to the logout redirect URI. + * Name of the post logout URI parameter which is added as a query parameter to the logout redirect URI. */ @ConfigItem(defaultValue = OidcConstants.POST_LOGOUT_REDIRECT_URI) public String postLogoutUriParam; /** - * Additional properties which will be added as the query parameters to the logout redirect URI. + * Additional properties which is added as the query parameters to the logout redirect URI. */ @ConfigItem public Map extraParams; @@ -388,13 +394,13 @@ public static class Backchannel { /** * Token cache timer interval. - * If this property is set then a timer will check and remove the stale entries periodically. + * If this property is set, a timer checks and removes the stale entries periodically. */ @ConfigItem public Optional cleanUpTimerInterval = Optional.empty(); /** - * Logout token claim whose value will be used as a key for caching the tokens. + * Logout token claim whose value is used as a key for caching the tokens. * Only `sub` (subject) and `sid` (session id) claims can be used as keys. * Set it to `sid` only if ID tokens issued by the OIDC provider have no `sub` but have `sid` claim. */ @@ -455,7 +461,7 @@ public static class Jwks { * If JWK verification keys should be fetched at the moment a connection to the OIDC provider * is initialized. *

- * Disabling this property will delay the key acquisition until the moment the current token + * Disabling this property delays the key acquisition until the moment the current token * has to be verified. Typically it can only be necessary if the token or other telated request properties * provide an additional context which is required to resolve the keys correctly. */ @@ -464,22 +470,22 @@ public static class Jwks { /** * Maximum number of JWK keys that can be cached. - * This property will be ignored if the {@link #resolveEarly} property is set to true. + * This property is ignored if the {@link #resolveEarly} property is set to true. */ @ConfigItem(defaultValue = "10") public int cacheSize = 10; /** * Number of minutes a JWK key can be cached for. - * This property will be ignored if the {@link #resolveEarly} property is set to true. + * This property is ignored if the {@link #resolveEarly} property is set to true. */ @ConfigItem(defaultValue = "10M") public Duration cacheTimeToLive = Duration.ofMinutes(10); /** * Cache timer interval. - * If this property is set then a timer will check and remove the stale entries periodically. - * This property will be ignored if the {@link #resolveEarly} property is set to true. + * If this property is set, a timer checks and removes the stale entries periodically. + * This property is ignored if the {@link #resolveEarly} property is set to true. */ @ConfigItem public Optional cleanUpTimerInterval = Optional.empty(); @@ -573,23 +579,23 @@ public enum Strategy { public boolean splitTokens; /** - * Mandates that the Default TokenStateManager will encrypt the session cookie that stores the tokens. + * Mandates that the Default TokenStateManager encrypt the session cookie that stores the tokens. */ @ConfigItem(defaultValue = "true") public boolean encryptionRequired = true; /** - * Secret which will be used by the Default TokenStateManager to encrypt the session cookie + * The secret used by the Default TokenStateManager to encrypt the session cookie * storing the tokens when {@link #encryptionRequired} property is enabled. *

* If this secret is not set, the client secret configured with - * either `quarkus.oidc.credentials.secret` or `quarkus.oidc.credentials.client-secret.value` will be checked. - * Finally, `quarkus.oidc.credentials.jwt.secret` which can be used for `client_jwt_secret` authentication will be + * either `quarkus.oidc.credentials.secret` or `quarkus.oidc.credentials.client-secret.value` is checked. + * Finally, `quarkus.oidc.credentials.jwt.secret` which can be used for `client_jwt_secret` authentication is * checked. - * The secret will be auto-generated if it remains uninitialized after checking all of these properties. + * The secret is auto-generated if it remains uninitialized after checking all of these properties. *

- * The length of the secret which will be used to encrypt the tokens should be at least 32 characters long. - * Warning will be logged if the secret length is less than 16 characters. + * The length of the secret used to encrypt the tokens should be at least 32 characters long. + * A warning is logged if the secret length is less than 16 characters. */ @ConfigItem public Optional encryptionSecret = Optional.empty(); @@ -738,18 +744,19 @@ public static Roles fromClaimPathAndSeparator(List path, String sep) { } /** - * List of paths to claims containing an array of groups. Each path starts from the top level JWT JSON object - * and can contain multiple segments where each segment represents a JSON object name only, - * example: "realm/groups". Use double quotes with the namespace qualified claim names. - * This property can be used if a token has no 'groups' claim but has the groups set in one or more different - * claims. + * A list of paths to claims containing an array of groups. + * Each path starts from the top level JWT JSON object + * and can contain multiple segments. + * Each segment represents a JSON object name only; for example: "realm/groups". + * Use double quotes with the namespace-qualified claim names. + * This property can be used if a token has no `groups` claim but has the groups set in one or more different claims. */ @ConfigItem public Optional> roleClaimPath = Optional.empty(); /** - * Separator for splitting a string which may contain multiple group values. - * It will only be used if the "role-claim-path" property points to one or more custom claims whose values are strings. - * A single space will be used by default because the standard 'scope' claim may contain a space separated sequence. + * The separator for splitting strings that contain multiple group values. + * It is only used if the "role-claim-path" property points to one or more custom claims whose values are strings. + * A single space is used by default because the standard `scope` claim can contain a space-separated sequence. */ @ConfigItem public Optional roleClaimSeparator = Optional.empty(); @@ -787,13 +794,13 @@ public void setSource(Source source) { // Source of the principal roles public static enum Source { /** - * ID Token - the default value for the 'web-app' applications. + * ID Token - the default value for the `web-app` applications. */ idtoken, /** - * Access Token - the default value for the 'service' applications; - * can also be used as the source of roles for the 'web-app' applications. + * Access Token - the default value for the `service` applications; + * can also be used as the source of roles for the `web-app` applications. */ accesstoken, @@ -831,59 +838,60 @@ public enum ResponseMode { /** * Authorization response parameters are encoded as HTML form values that are auto-submitted in the browser - * and transmitted via the HTTP POST method using the application/x-www-form-urlencoded content type + * and transmitted by the HTTP POST method using the application/x-www-form-urlencoded content type */ FORM_POST } /** - * Authorization code flow response mode + * Authorization code flow response mode. */ @ConfigItem(defaultValueDocumentation = "query") public Optional responseMode = Optional.empty(); /** - * Relative path for calculating a `redirect_uri` query parameter. - * It has to start from a forward slash and will be appended to the request URI's host and port. - * For example, if the current request URI is 'https://localhost:8080/service' then a `redirect_uri` parameter - * will be set to 'https://localhost:8080/' if this property is set to '/' and be the same as the request URI + * The relative path for calculating a `redirect_uri` query parameter. + * It has to start from a forward slash and is appended to the request URI's host and port. + * For example, if the current request URI is `https://localhost:8080/service`, a `redirect_uri` parameter + * is set to `https://localhost:8080/` if this property is set to `/` and be the same as the request URI * if this property has not been configured. - * Note the original request URI will be restored after the user has authenticated if 'restorePathAfterRedirect' is set + * Note the original request URI is restored after the user has authenticated if `restorePathAfterRedirect` is set * to `true`. */ @ConfigItem public Optional redirectPath = Optional.empty(); /** - * If this property is set to `true` then the original request URI which was used before - * the authentication will be restored after the user has been redirected back to the application. + * If this property is set to `true`, the original request URI which was used before + * the authentication is restored after the user has been redirected back to the application. * - * Note if `redirectPath` property is not set, the original request URI will be restored even if this property is + * Note if `redirectPath` property is not set, the original request URI is restored even if this property is * disabled. */ @ConfigItem(defaultValue = "false") public boolean restorePathAfterRedirect; /** - * Remove the query parameters such as 'code' and 'state' set by the OIDC server on the redirect URI + * Remove the query parameters such as `code` and `state` set by the OIDC server on the redirect URI * after the user has authenticated by redirecting a user to the same URI but without the query parameters. */ @ConfigItem(defaultValue = "true") public boolean removeRedirectParameters = true; /** - * Relative path to the public endpoint which will process the error response from the OIDC authorization endpoint. - * If the user authentication has failed then the OIDC provider will return an `error` and an optional + * Relative path to the public endpoint which processes the error response from the OIDC authorization + * endpoint. + * If the user authentication has failed, the OIDC provider returns an `error` and an optional * `error_description` - * parameters, instead of the expected authorization 'code'. + * parameters, instead of the expected authorization `code`. * - * If this property is set then the user will be redirected to the endpoint which can return a user-friendly - * error description page. It has to start from a forward slash and will be appended to the request URI's host and port. - * For example, if it is set as '/error' and the current request URI is - * 'https://localhost:8080/callback?error=invalid_scope' - * then a redirect will be made to 'https://localhost:8080/error?error=invalid_scope'. + * If this property is set, the user is redirected to the endpoint which can return a user-friendly + * error description page. It has to start from a forward slash and is appended to the request URI's host and port. + * For example, if it is set as `/error` and the current request URI is + * `https://localhost:8080/callback?error=invalid_scope`, + * a redirect is made to `https://localhost:8080/error?error=invalid_scope`. * - * If this property is not set then HTTP 401 status will be returned in case of the user authentication failure. + * If this property is not set, HTTP 401 status is returned in case of the user authentication failure. */ @ConfigItem public Optional errorPath = Optional.empty(); @@ -895,8 +903,8 @@ public enum ResponseMode { * Access token is not verified by default since it is meant to be propagated to the downstream services. * The verification of the access token should be enabled if it is injected as a JWT token. * - * Access tokens obtained as part of the code flow will always be verified if `quarkus.oidc.roles.source` - * property is set to `accesstoken` which means the authorization decision will be based on the roles extracted from the + * Access tokens obtained as part of the code flow are always verified if `quarkus.oidc.roles.source` + * property is set to `accesstoken` which means the authorization decision is based on the roles extracted from the * access token. * * Bearer access tokens are always verified. @@ -905,8 +913,9 @@ public enum ResponseMode { public boolean verifyAccessToken; /** - * Force 'https' as the `redirect_uri` parameter scheme when running behind an SSL/TLS terminating reverse proxy. - * This property, if enabled, will also affect the logout `post_logout_redirect_uri` and the local redirect requests. + * Force `https` as the `redirect_uri` parameter scheme when running behind an SSL/TLS terminating reverse + * proxy. + * This property, if enabled, also affects the logout `post_logout_redirect_uri` and the local redirect requests. */ @ConfigItem(defaultValueDocumentation = "false") public Optional forceRedirectHttpsScheme = Optional.empty(); @@ -927,29 +936,29 @@ public enum ResponseMode { public boolean nonceRequired = false; /** - * Add the `openid` scope automatically to the list of scopes. This is required for OpenId Connect providers - * but will not work for OAuth2 providers such as Twitter OAuth2 which does not accept that scope and throws an error. + * Add the `openid` scope automatically to the list of scopes. This is required for OpenId Connect providers, + * but does not work for OAuth2 providers such as Twitter OAuth2, which do not accept this scope and throw errors. */ @ConfigItem(defaultValueDocumentation = "true") public Optional addOpenidScope = Optional.empty(); /** - * Additional properties which will be added as the query parameters to the authentication redirect URI. + * Additional properties added as query parameters to the authentication redirect URI. */ @ConfigItem public Map extraParams = new HashMap<>(); /** - * Request URL query parameters which, if present, will be added to the authentication redirect URI. + * Request URL query parameters which, if present, are added to the authentication redirect URI. */ @ConfigItem @ConvertWith(TrimmedStringConverter.class) public Optional> forwardParams = Optional.empty(); /** - * If enabled the state, session and post logout cookies will have their 'secure' parameter set to `true` - * when HTTP is used. It may be necessary when running behind an SSL/TLS terminating reverse proxy. - * The cookies will always be secure if HTTPS is used even if this property is set to false. + * If enabled the state, session, and post logout cookies have their `secure` parameter set to `true` + * when HTTP is used. It might be necessary when running behind an SSL/TLS terminating reverse proxy. + * The cookies are always secure if HTTPS is used, even if this property is set to false. */ @ConfigItem(defaultValue = "false") public boolean cookieForceSecure; @@ -963,23 +972,23 @@ public enum ResponseMode { public Optional cookieSuffix = Optional.empty(); /** - * Cookie path parameter value which, if set, will be used to set a path parameter for the session, state and post + * Cookie path parameter value which, if set, is used to set a path parameter for the session, state and post * logout cookies. - * The `cookie-path-header` property, if set, will be checked first. + * The `cookie-path-header` property, if set, is checked first. */ @ConfigItem(defaultValue = "/") public String cookiePath = "/"; /** * Cookie path header parameter value which, if set, identifies the incoming HTTP header - * whose value will be used to set a path parameter for the session, state and post logout cookies. - * If the header is missing then the `cookie-path` property will be checked. + * whose value is used to set a path parameter for the session, state and post logout cookies. + * If the header is missing, the `cookie-path` property is checked. */ @ConfigItem public Optional cookiePathHeader = Optional.empty(); /** - * Cookie domain parameter value which, if set, will be used for the session, state and post logout cookies. + * Cookie domain parameter value which, if set, is used for the session, state and post logout cookies. */ @ConfigItem public Optional cookieDomain = Optional.empty(); @@ -991,11 +1000,11 @@ public enum ResponseMode { public CookieSameSite cookieSameSite = CookieSameSite.LAX; /** - * If a state cookie is present then a `state` query parameter must also be present and both the state - * cookie name suffix and state cookie value have to match the value of the `state` query parameter when + * If a state cookie is present, a `state` query parameter must also be present and both the state + * cookie name suffix and state cookie value must match the value of the `state` query parameter when * the redirect path matches the current path. * However, if multiple authentications are attempted from the same browser, for example, from the different - * browser tabs, then the currently available state cookie may represent the authentication flow + * browser tabs, then the currently available state cookie might represent the authentication flow * initiated from another tab and not related to the current request. * Disable this property to permit only a single authorization code flow in the same browser. * @@ -1010,29 +1019,29 @@ public enum ResponseMode { * matches the original request URL, the stale state cookie might remain in the browser cache from * the earlier failed redirect to an OpenId Connect provider and be visible during the current request. * For example, if Single-page application (SPA) uses XHR to handle redirects to the provider - * which does not support CORS for its authorization endpoint, the browser will block it - * and the state cookie created by Quarkus will remain in the browser cache. - * Quarkus will report an authentication failure when it will detect such an old state cookie but find no matching state + * which does not support CORS for its authorization endpoint, the browser blocks it + * and the state cookie created by Quarkus remains in the browser cache. + * Quarkus reports an authentication failure when it detects such an old state cookie but find no matching state * query parameter. *

- * Reporting HTTP 401 error is usually the right thing to do in such cases, it will minimize a risk of the + * Reporting HTTP 401 error is usually the right thing to do in such cases, it minimizes a risk of the * browser redirect loop but also can identify problems in the way SPA or Quarkus application manage redirects. * For example, enabling {@link #javaScriptAutoRedirect} or having the provider redirect to URL configured - * with {@link #redirectPath} may be needed to avoid such errors. + * with {@link #redirectPath} might be needed to avoid such errors. *

- * However, setting this property to `false` may help if the above options are not suitable. - * It will cause a new authentication redirect to OpenId Connect provider. Doing so may increase the + * However, setting this property to `false` might help if the above options are not suitable. + * It causes a new authentication redirect to OpenId Connect provider. Doing so might increase the * risk of browser redirect loops. */ @ConfigItem(defaultValue = "false") public boolean failOnMissingStateParam = false; /** - * If this property is set to `true` then an OIDC UserInfo endpoint will be called. - * This property will be enabled if `quarkus.oidc.roles.source` is `userinfo` + * If this property is set to `true`, an OIDC UserInfo endpoint is called. + * This property is enabled if `quarkus.oidc.roles.source` is `userinfo`. * or `quarkus.oidc.token.verify-access-token-with-user-info` is `true` * or `quarkus.oidc.authentication.id-token-required` is set to `false`, - * you do not have to enable this property manually in these cases. + * you do not need to enable this property manually in these cases. */ @ConfigItem(defaultValueDocumentation = "false") public Optional userInfoRequired = Optional.empty(); @@ -1040,24 +1049,25 @@ public enum ResponseMode { /** * Session age extension in minutes. * The user session age property is set to the value of the ID token life-span by default and - * the user will be redirected to the OIDC provider to re-authenticate once the session has expired. - * If this property is set to a non-zero value, then the expired ID token can be refreshed before + * the user is redirected to the OIDC provider to re-authenticate once the session has expired. + * If this property is set to a nonzero value, then the expired ID token can be refreshed before * the session has expired. - * This property will be ignored if the `token.refresh-expired` property has not been enabled. + * This property is ignored if the `token.refresh-expired` property has not been enabled. */ @ConfigItem(defaultValue = "5M") public Duration sessionAgeExtension = Duration.ofMinutes(5); /** - * If this property is set to `true` then a normal 302 redirect response will be returned - * if the request was initiated via JavaScript API such as XMLHttpRequest or Fetch and the current user needs to be - * (re)authenticated which may not be desirable for Single-page applications (SPA) since - * it automatically following the redirect may not work given that OIDC authorization endpoints typically do not support + * If this property is set to `true`, a normal 302 redirect response is returned + * if the request was initiated by a JavaScript API such as XMLHttpRequest or Fetch and the current user needs to be + * (re)authenticated, which might not be desirable for Single-page applications (SPA) since + * it automatically following the redirect might not work given that OIDC authorization endpoints typically do not + * support * CORS. *

- * If this property is set to 'false' then a status code of '499' will be returned to allow + * If this property is set to `false`, a status code of `499` is returned to allow * SPA to handle the redirect manually if a request header identifying current request as a JavaScript request is found. - * 'X-Requested-With' request header with its value set to either `JavaScript` or `XMLHttpRequest` is expected by + * `X-Requested-With` request header with its value set to either `JavaScript` or `XMLHttpRequest` is expected by * default if * this property is enabled. You can register a custom {@linkplain JavaScriptRequestChecker} to do a custom JavaScript * request check instead. @@ -1068,7 +1078,7 @@ public enum ResponseMode { /** * Requires that ID token is available when the authorization code flow completes. * Disable this property only when you need to use the authorization code flow with OAuth2 providers which do not return - * ID token - an internal IdToken will be generated in such cases. + * ID token - an internal IdToken is generated in such cases. */ @ConfigItem(defaultValueDocumentation = "true") public Optional idTokenRequired = Optional.empty(); @@ -1087,29 +1097,30 @@ public enum ResponseMode { public Optional pkceRequired = Optional.empty(); /** - * Secret which will be used to encrypt a Proof Key for Code Exchange (PKCE) code verifier in the code flow state. + * Secret used to encrypt a Proof Key for Code Exchange (PKCE) code verifier in the code flow state. * This secret should be at least 32 characters long. * - * @deprecated Use {@link #stateSecret} property instead. + * @deprecated This field is deprecated. Use {@link #stateSecret} instead. + * */ @ConfigItem @Deprecated(forRemoval = true) public Optional pkceSecret = Optional.empty(); /** - * Secret which will be used to encrypt Proof Key for Code Exchange (PKCE) code verifier and/or nonce in the code flow + * Secret used to encrypt Proof Key for Code Exchange (PKCE) code verifier and/or nonce in the code flow * state. * This secret should be at least 32 characters long. *

* If this secret is not set, the client secret configured with - * either `quarkus.oidc.credentials.secret` or `quarkus.oidc.credentials.client-secret.value` will be checked. - * Finally, `quarkus.oidc.credentials.jwt.secret` which can be used for `client_jwt_secret` authentication will be - * checked. Client secret will not be used as a state encryption secret if it is less than 32 characters + * either `quarkus.oidc.credentials.secret` or `quarkus.oidc.credentials.client-secret.value` is checked. + * Finally, `quarkus.oidc.credentials.jwt.secret` which can be used for `client_jwt_secret` authentication is + * checked. A client secret is not be used as a state encryption secret if it is less than 32 characters * long. *

- * The secret will be auto-generated if it remains uninitialized after checking all of these properties. + * The secret is auto-generated if it remains uninitialized after checking all of these properties. *

- * Error will be reported if the secret length is less than 16 characters. + * Error is reported if the secret length is less than 16 characters. */ @ConfigItem public Optional stateSecret = Optional.empty(); @@ -1341,13 +1352,13 @@ public static class CodeGrant { /** * Additional parameters, in addition to the required `code` and `redirect-uri` parameters, - * which have to be included to complete the authorization code grant request. + * which must be included to complete the authorization code grant request. */ @ConfigItem public Map extraParams = new HashMap<>(); /** - * Custom HTTP headers which have to be sent to complete the authorization code grant request. + * Custom HTTP headers which must be sent to complete the authorization code grant request. */ @ConfigItem public Map headers = new HashMap<>(); @@ -1411,11 +1422,11 @@ public static Token fromAudience(String... audience) { } /** - * Expected issuer `iss` claim value. - * Note this property overrides the `issuer` property which may be set in OpenId Connect provider's well-known + * The expected issuer `iss` claim value. + * This property overrides the `issuer` property, which might be set in OpenId Connect provider's well-known * configuration. - * If the `iss` claim value varies depending on the host/IP address or tenant id of the provider then you may skip the - * issuer verification by setting this property to 'any' but it should be done only when other options (such as + * If the `iss` claim value varies depending on the host, IP address, or tenant id of the provider, you can skip the + * issuer verification by setting this property to `any`, but it should be done only when other options (such as * configuring * the provider to use the fixed `iss` claim value) are not possible. */ @@ -1423,15 +1434,15 @@ public static Token fromAudience(String... audience) { public Optional issuer = Optional.empty(); /** - * Expected audience 'aud' claim value which may be a string or an array of strings. + * The expected audience `aud` claim value, which can be a string or an array of strings. * - * Note the audience claim will be verified for ID tokens by default. + * Note the audience claim is verified for ID tokens by default. * ID token audience must be equal to the value of `quarkus.oidc.client-id` property. * Use this property to override the expected value if your OpenID Connect provider * sets a different audience claim value in ID tokens. Set it to `any` if your provider * does not set ID token audience` claim. * - * Audience verification for access tokens will only be done if this property is configured. + * Audience verification for access tokens is only done if this property is configured. */ @ConfigItem public Optional> audience = Optional.empty(); @@ -1439,7 +1450,7 @@ public static Token fromAudience(String... audience) { /** * Require that the token includes a `sub` (subject) claim which is a unique * and never reassigned identifier for the current user. - * Note that if you enable this property and if UserInfo is also required then + * Note that if you enable this property and if UserInfo is also required, * both the token and UserInfo `sub` claims must be present and match each other. */ @ConfigItem(defaultValue = "false") @@ -1476,22 +1487,23 @@ public static Token fromAudience(String... audience) { * Token age. * * It allows for the number of seconds to be specified that must not elapse since the `iat` (issued at) time. - * A small leeway to account for clock skew which can be configured with 'quarkus.oidc.token.lifespan-grace' to verify + * A small leeway to account for clock skew which can be configured with `quarkus.oidc.token.lifespan-grace` to verify * the token expiry time * can also be used to verify the token age property. * * Note that setting this property does not relax the requirement that Bearer and Code Flow JWT tokens - * must have a valid ('exp') expiry claim value. The only exception where setting this property relaxes the requirement + * must have a valid (`exp`) expiry claim value. The only exception where setting this property relaxes the requirement * is when a logout token is sent with a back-channel logout request since the current - * OpenId Connect Back-Channel specification does not explicitly require the logout tokens to contain an 'exp' claim. - * However, even if the current logout token is allowed to have no 'exp' claim, the `exp` claim will be still verified + * OpenId Connect Back-Channel specification does not explicitly require the logout tokens to contain an `exp` claim. + * However, even if the current logout token is allowed to have no `exp` claim, the `exp` claim is still verified * if the logout token contains it. */ @ConfigItem public Optional age = Optional.empty(); /** - * Name of the claim which contains a principal name. By default, the `upn`, `preferred_username` and `sub` claims are + * Name of the claim which contains a principal name. By default, the `upn`, `preferred_username` and `sub` + * claims are * checked. */ @ConfigItem @@ -1499,34 +1511,34 @@ public static Token fromAudience(String... audience) { /** * Refresh expired authorization code flow ID or access tokens. - * If this property is enabled then a refresh token request will be performed if the authorization code - * ID or access token has expired and, if successful, the local session will be updated with the new set of tokens. - * Otherwise, the local session will be invalidated and the user redirected to the OpenID Provider to re-authenticate. - * In this case the user may not be challenged again if the OIDC provider session is still active. + * If this property is enabled, a refresh token request is performed if the authorization code + * ID or access token has expired and, if successful, the local session is updated with the new set of tokens. + * Otherwise, the local session is invalidated and the user redirected to the OpenID Provider to re-authenticate. + * In this case, the user might not be challenged again if the OIDC provider session is still active. * - * For this option be effective the `authentication.session-age-extension` property should also be set to a non-zero + * For this option be effective the `authentication.session-age-extension` property should also be set to a nonzero * value since the refresh token is currently kept in the user session. * * This option is valid only when the application is of type {@link ApplicationType#WEB_APP}}. * - * This property will be enabled if `quarkus.oidc.token.refresh-token-time-skew` is configured, - * you do not have to enable this property manually in this case. + * This property is enabled if `quarkus.oidc.token.refresh-token-time-skew` is configured, + * you do not need to enable this property manually in this case. */ @ConfigItem public boolean refreshExpired; /** - * Refresh token time skew in seconds. - * If this property is enabled then the configured number of seconds is added to the current time + * The refresh token time skew, in seconds. + * If this property is enabled, the configured number of seconds is added to the current time * when checking if the authorization code ID or access token should be refreshed. - * If the sum is greater than the authorization code ID or access token's expiration time then a refresh is going to + * If the sum is greater than the authorization code ID or access token's expiration time, a refresh is going to * happen. */ @ConfigItem public Optional refreshTokenTimeSkew = Optional.empty(); /** - * Forced JWK set refresh interval in minutes. + * The forced JWK set refresh interval in minutes. */ @ConfigItem(defaultValue = "10M") public Duration forcedJwkRefreshInterval = Duration.ofMinutes(10); @@ -1556,12 +1568,11 @@ public static Token fromAudience(String... audience) { * Decryption key location. * JWT tokens can be inner-signed and encrypted by OpenId Connect providers. * However, it is not always possible to remotely introspect such tokens because - * the providers may not control the private decryption keys. + * the providers might not control the private decryption keys. * In such cases set this property to point to the file containing the decryption private key in * PEM or JSON Web Key (JWK) format. - * Note that if a `private_key_jwt` client authentication method is used then the private key - * which is used to sign client authentication JWT tokens will be used to try to decrypt an encrypted ID token - * if this property is not set. + * If this property is not set and the `private_key_jwt` client authentication method is used, the private key + * used to sign the client authentication JWT tokens are also used to decrypt the encrypted ID tokens. */ @ConfigItem public Optional decryptionKeyLocation = Optional.empty(); @@ -1569,10 +1580,10 @@ public static Token fromAudience(String... audience) { /** * Allow the remote introspection of JWT tokens when no matching JWK key is available. * - * Note this property is set to `true` by default for backward-compatibility reasons and will be set to `false` - * instead in one of the next releases. + * This property is set to `true` by default for backward-compatibility reasons. It is planned that this default value + * will be changed to `false` in an upcoming release. * - * Also note this property will be ignored if JWK endpoint URI is not available and introspecting the tokens is + * Also note this property is ignored if JWK endpoint URI is not available and introspecting the tokens is * the only verification option. */ @ConfigItem(defaultValue = "true") @@ -1588,7 +1599,7 @@ public static Token fromAudience(String... audience) { /** * Allow the remote introspection of the opaque tokens. * - * Set this property to 'false' if only JWT tokens are expected. + * Set this property to `false` if only JWT tokens are expected. */ @ConfigItem(defaultValue = "true") public boolean allowOpaqueTokenIntrospection = true; @@ -1606,9 +1617,9 @@ public static Token fromAudience(String... audience) { /** * Indirectly verify that the opaque (binary) access token is valid by using it to request UserInfo. * Opaque access token is considered valid if the provider accepted this token and returned a valid UserInfo. - * You should only enable this option if the opaque access tokens have to be accepted but OpenId Connect + * You should only enable this option if the opaque access tokens must be accepted but OpenId Connect * provider does not have a token introspection endpoint. - * This property will have no effect when JWT tokens have to be verified. + * This property has no effect when JWT tokens must be verified. */ @ConfigItem(defaultValueDocumentation = "false") public Optional verifyAccessTokenWithUserInfo = Optional.empty(); @@ -1790,7 +1801,7 @@ public static enum ApplicationType { /** * A combined {@code SERVICE} and {@code WEB_APP} client. - * For this type of client, the Bearer Authorization method will be used if the Authorization header is set + * For this type of client, the Bearer Authorization method is used if the Authorization header is set * and Authorization Code Flow - if not. */ HYBRID From 1069081957ca60908bac32bba4282f6d4acea341 Mon Sep 17 00:00:00 2001 From: Martin Kouba Date: Wed, 17 Jan 2024 16:10:05 +0100 Subject: [PATCH 07/42] Qute: fix UserTagSectionHelper.Arguments.asHtmlAttributes() - resolves #38251 (cherry picked from commit 8b445f1608b3d2fddc693e6832ee6741f97a81fb) --- .../io/quarkus/qute/UserTagSectionHelper.java | 28 ++++++++++++------- .../java/io/quarkus/qute/UserTagTest.java | 7 +++-- 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/independent-projects/qute/core/src/main/java/io/quarkus/qute/UserTagSectionHelper.java b/independent-projects/qute/core/src/main/java/io/quarkus/qute/UserTagSectionHelper.java index 5781d6d52d82c..e0f3d9ef1e8c8 100644 --- a/independent-projects/qute/core/src/main/java/io/quarkus/qute/UserTagSectionHelper.java +++ b/independent-projects/qute/core/src/main/java/io/quarkus/qute/UserTagSectionHelper.java @@ -16,10 +16,13 @@ public class UserTagSectionHelper extends IncludeSectionHelper implements Sectio protected final boolean isNestedContentNeeded; + private final HtmlEscaper htmlEscaper; + UserTagSectionHelper(Supplier