From f6c20569703c84ab1014f93231b6c25a662e978f Mon Sep 17 00:00:00 2001 From: Rolfe Dlugy-Hegwer Date: Thu, 11 Jul 2024 11:53:10 -0400 Subject: [PATCH] Apply QE feedback to community docs --- .../security-authentication-mechanisms.adoc | 3 ++ .../security-getting-started-tutorial.adoc | 2 +- docs/src/main/asciidoc/security-jwt.adoc | 6 +-- .../security-oidc-auth0-tutorial.adoc | 4 +- ...-bearer-token-authentication-tutorial.adoc | 10 ++-- ...rity-oidc-bearer-token-authentication.adoc | 36 +++++++------ ...idc-code-flow-authentication-tutorial.adoc | 4 +- ...ecurity-oidc-code-flow-authentication.adoc | 54 ++++++++++--------- ...urity-openid-connect-client-reference.adoc | 10 ++-- .../security-openid-connect-client.adoc | 8 +-- .../security-openid-connect-dev-services.adoc | 2 +- docs/src/main/asciidoc/security-testing.adoc | 4 +- 12 files changed, 79 insertions(+), 64 deletions(-) diff --git a/docs/src/main/asciidoc/security-authentication-mechanisms.adoc b/docs/src/main/asciidoc/security-authentication-mechanisms.adoc index 2f564939a6906..ddf3e14c20d94 100644 --- a/docs/src/main/asciidoc/security-authentication-mechanisms.adoc +++ b/docs/src/main/asciidoc/security-authentication-mechanisms.adoc @@ -48,7 +48,10 @@ ifndef::no-webauthn-authentication[] |WebAuthn |xref:security-webauthn.adoc[WebAuthn] endif::no-webauthn-authentication[] +ifndef::no-quarkus-kerberos[] |Kerberos ticket |link:https://quarkiverse.github.io/quarkiverse-docs/quarkus-kerberos/dev/index.html[Kerberos] +endif::no-quarkus-kerberos[] + |==== For more information, see the following <> table. diff --git a/docs/src/main/asciidoc/security-getting-started-tutorial.adoc b/docs/src/main/asciidoc/security-getting-started-tutorial.adoc index 81bc7784babf5..905406a448e15 100644 --- a/docs/src/main/asciidoc/security-getting-started-tutorial.adoc +++ b/docs/src/main/asciidoc/security-getting-started-tutorial.adoc @@ -46,7 +46,7 @@ To examine the completed example, download the {quickstarts-archive-url}[archive git clone {quickstarts-clone-url} ---- -You can find the solution in the `security-jpa-quickstart` link:{quickstarts-tree-url}/security-jpa-quickstart[directory]. +You can find the solution in the `security-jpa-quickstart` link:{quickstarts-tree-url}/security-jpa-quickstart/[directory]. ==== :sectnums: diff --git a/docs/src/main/asciidoc/security-jwt.adoc b/docs/src/main/asciidoc/security-jwt.adoc index 30742afb2ba13..5c759361eedd6 100644 --- a/docs/src/main/asciidoc/security-jwt.adoc +++ b/docs/src/main/asciidoc/security-jwt.adoc @@ -825,7 +825,7 @@ Please see the xref:security-openid-connect-client-reference.adoc#token-propagat [[integration-testing-wiremock]] ==== Wiremock -If you configure `mp.jwt.verify.publickey.location` to point to HTTPS or HTTP based JsonWebKey (JWK) set then you can use the same approach as described in the xref:security-oidc-bearer-token-authentication.adoc#integration-testing[OpenID Connect Bearer Token Integration testing] `Wiremock` section but only change the `application.properties` to use MP JWT configuration properties instead: +If you configure `mp.jwt.verify.publickey.location` to point to HTTPS or HTTP based JsonWebKey (JWK) set then you can use the same approach as described in the xref:security-oidc-bearer-token-authentication.adoc#bearer-token-integration-testing[OpenID Connect Bearer Token Integration testing] `Wiremock` section but only change the `application.properties` to use MP JWT configuration properties instead: [source, properties] ---- @@ -837,7 +837,7 @@ mp.jwt.verify.issuer=${keycloak.url}/realms/quarkus [[integration-testing-keycloak]] ==== Keycloak -If you work with Keycloak and configure `mp.jwt.verify.publickey.location` to point to HTTPS or HTTP based JsonWebKey (JWK) set then you can use the same approach as described in the xref:security-oidc-bearer-token-authentication.adoc#integration-testing[OpenID Connect Bearer Token Integration testing] Keycloak section but only change the `application.properties` to use MP JWT configuration properties instead: +If you work with Keycloak and configure `mp.jwt.verify.publickey.location` to point to HTTPS or HTTP based JsonWebKey (JWK) set then you can use the same approach as described in the xref:security-oidc-bearer-token-authentication.adoc#bearer-token-integration-testing[OpenID Connect Bearer Token Integration testing] Keycloak section but only change the `application.properties` to use MP JWT configuration properties instead: [source, properties] ---- @@ -865,7 +865,7 @@ mp.jwt.verify.issuer=${client.quarkus.oidc.auth-server-url} [[integration-testing-public-key]] ==== Local Public Key -You can use the same approach as described in the xref:security-oidc-bearer-token-authentication.adoc#integration-testing[OpenID Connect Bearer Token Integration testing] `Local Public Key` section but only change the `application.properties` to use MP JWT configuration properties instead: +You can use the same approach as described in the xref:security-oidc-bearer-token-authentication.adoc#bearer-token-integration-testing[OpenID Connect Bearer Token Integration testing] `Local Public Key` section but only change the `application.properties` to use MP JWT configuration properties instead: [source, properties] ---- diff --git a/docs/src/main/asciidoc/security-oidc-auth0-tutorial.adoc b/docs/src/main/asciidoc/security-oidc-auth0-tutorial.adoc index 6ee2b51a4e7cd..8f2708f66467b 100644 --- a/docs/src/main/asciidoc/security-oidc-auth0-tutorial.adoc +++ b/docs/src/main/asciidoc/security-oidc-auth0-tutorial.adoc @@ -929,7 +929,7 @@ Press `r` and notice this test failing with `403` which is expected because the image::auth0-test-failure-403.png[Auth0 test failure 403] -Before fixing the test, let's review the options available for testing Quarkus endpoints secured by OIDC. These options might vary, depending on which flow your application supports and how you prefer to test. Endpoints which use OIDC authorization code flow can be tested using xref:security-oidc-code-flow-authentication#integration-testing[one of these options] and endpoints which use Bearer token authentication can be tested using xref:security-oidc-bearer-token-authentication#integration-testing[one of these options]. +Before fixing the test, let's review the options available for testing Quarkus endpoints secured by OIDC. These options might vary, depending on which flow your application supports and how you prefer to test. Endpoints which use OIDC authorization code flow can be tested using xref:security-oidc-code-flow-authentication#code-flow-integration-testing[one of these options] and endpoints which use Bearer token authentication can be tested using xref:security-oidc-bearer-token-authentication#bearer-token-integration-testing[one of these options]. As you can see, testing of the endpoints secured with Auth0 can be done with the help of `Wiremock`, or `@TestSecurity` annotation. Experiment with writing such tests on your own and reach out if you encounter any problems. @@ -957,7 +957,7 @@ image::auth0-password-grant.png[Auth0 password grant] It is important to clarify that we do not recommend using the deprecated OAuth2 `password` token grant in production. However using it can help testing the endpoint with tokens acquired from the live dev Auth0 tenant. ==== -`OidcTestClient` should be used to test applications accepting bearer tokens which will work for the endpoint developed in this tutorial as it supports both authorization code flow and bearer token authentication. You would need to use OIDC WireMock or `HtmlUnit` directly against the Auth0 dev tenant if only the authorization code flow was supported - in the latter case `HtmlUnit` test code would have to be aligned with how Auth0 challenges users to enter their credentials. If you like, you can copy the xref:security-oidc-code-flow-authentication#integration-testing-wiremock[HtmlUnit test fragment] from the documentation and experiment with it. +`OidcTestClient` should be used to test applications accepting bearer tokens which will work for the endpoint developed in this tutorial as it supports both authorization code flow and bearer token authentication. You would need to use OIDC WireMock or `HtmlUnit` directly against the Auth0 dev tenant if only the authorization code flow was supported - in the latter case `HtmlUnit` test code would have to be aligned with how Auth0 challenges users to enter their credentials. If you like, you can copy the xref:security-oidc-code-flow-authentication#code-flow-integration-testing-wiremock[HtmlUnit test fragment] from the documentation and experiment with it. In meantime we will now proceed with fixing the currently failing test using `OidcTestClient`. diff --git a/docs/src/main/asciidoc/security-oidc-bearer-token-authentication-tutorial.adoc b/docs/src/main/asciidoc/security-oidc-bearer-token-authentication-tutorial.adoc index 2846b85a2e908..7887e47c82b12 100644 --- a/docs/src/main/asciidoc/security-oidc-bearer-token-authentication-tutorial.adoc +++ b/docs/src/main/asciidoc/security-oidc-bearer-token-authentication-tutorial.adoc @@ -190,7 +190,7 @@ Where: * `%prod.quarkus.oidc.auth-server-url` sets the base URL of the OpenID Connect (OIDC) server. The `%prod.` profile prefix ensures that `Dev Services for Keycloak` launches a container when you run the application in development (dev) mode. -For more information, see the <> section. +For more information, see the <> section. * `quarkus.oidc.client-id` sets a client id that identifies the application. * `quarkus.oidc.credentials.secret` sets the client secret, which is used by the `client_secret_basic` authentication method. @@ -206,7 +206,7 @@ You do not need to do this if you have already built a link:{quickstarts-tree-ur [NOTE] ==== Do not start the Keycloak server when you run the application in dev mode; `Dev Services for Keycloak` will start a container. -For more information, see the <> section. +For more information, see the <> section. ==== + . To start a Keycloak server, you can use Docker to run the following command: @@ -238,7 +238,7 @@ endif::no-quarkus-keycloak-admin-client[] -[[keycloak-dev-mode]] +[[bearer-token-tutorial-keycloak-dev-mode]] == Run the application in dev mode . To run the application in dev mode, run the following commands: @@ -301,7 +301,7 @@ include::{includes}/devtools/build-native.adoc[] == Test the application -For information about testing your application in dev mode, see the preceding <> section. +For information about testing your application in dev mode, see the preceding <> section. You can test the application launched in JVM or native modes with `curl`. @@ -352,7 +352,7 @@ export access_token=$(\ ) ---- -For information about writing integration tests that depend on `Dev Services for Keycloak`, see the xref:security-oidc-bearer-token-authentication.adoc#integration-testing-keycloak-devservices[Dev Services for Keycloak] section of the "OpenID Connect (OIDC) Bearer token authentication" guide. +For information about writing integration tests that depend on `Dev Services for Keycloak`, see the xref:security-oidc-bearer-token-authentication.adoc#bearer-token-integration-testing-keycloak-devservices[Dev Services for Keycloak] section of the "OpenID Connect (OIDC) Bearer token authentication" guide. //:sectnums!: diff --git a/docs/src/main/asciidoc/security-oidc-bearer-token-authentication.adoc b/docs/src/main/asciidoc/security-oidc-bearer-token-authentication.adoc index 4907c4fddaff3..a8b6995aeeb7b 100644 --- a/docs/src/main/asciidoc/security-oidc-bearer-token-authentication.adoc +++ b/docs/src/main/asciidoc/security-oidc-bearer-token-authentication.adoc @@ -88,14 +88,14 @@ Injection of `JsonWebToken` is supported in `@ApplicationScoped`, `@Singleton`, However, the use of `@RequestScoped` is required if the individual claims are injected as simple types. For more information, see the xref:security-jwt.adoc#supported-injection-scopes[Supported injection scopes] section of the Quarkus "Using JWT RBAC" guide. -[[user-info]] +[[bearer-token-user-info]] === `UserInfo` If you must request a UserInfo JSON object from the OIDC `UserInfo` endpoint, set `quarkus.oidc.authentication.user-info-required=true`. A request is sent to the OIDC provider `UserInfo` endpoint, and an `io.quarkus.oidc.UserInfo` (a simple `javax.json.JsonObject` wrapper) object is created. `io.quarkus.oidc.UserInfo` can be injected or accessed as a `SecurityIdentity` `userinfo` attribute. -[[config-metadata]] +[[bearer-token-config-metadata]] === Configuration metadata The current tenant's discovered link:https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata[OpenID Connect Configuration Metadata] is represented by `io.quarkus.oidc.OidcConfigurationMetadata` and can be injected or accessed as a `SecurityIdentity` `configuration-metadata` attribute. @@ -201,7 +201,7 @@ public class ProtectedResource { For more information about the `io.quarkus.security.PermissionsAllowed` annotation, see the xref:security-authorize-web-endpoints-reference.adoc#permission-annotation[Permission annotation] section of the "Authorization of web endpoints" guide. -[[token-verification-introspection]] +[[bearer-token-token-verification-introspection]] === Token verification and introspection If the token is a JWT token, then, by default, it is verified with a `JsonWebKey` (JWK) key from a local `JsonWebKeySet`, retrieved from the OIDC provider's JWK endpoint. @@ -250,7 +250,7 @@ A disadvantage is that a remote OIDC metadata discovery call is required to disc The `io.quarkus.oidc.TokenIntrospection`, a simple `jakarta.json.JsonObject` wrapper object, will be created. It can be injected or accessed as a `SecurityIdentity` `introspection` attribute, providing either the JWT or opaque token has been successfully introspected. -[[token-introspection-userinfo-cache]] +[[bearer-token-token-introspection-userinfo-cache]] === Token introspection and `UserInfo` cache All opaque access tokens must be remotely introspected. @@ -299,7 +299,7 @@ Additionally, the cleanup timer, if activated, periodically checks for expired e You can experiment with the default cache implementation or register a custom one. -[[jwt-claim-verification]] +[[bearer-token-jwt-claim-verification]] === JSON Web Token claim verification After the bearer JWT token's signature has been verified and its `expires at` (`exp`) claim has been checked, the `iss` (`issuer`) claim value is verified next. @@ -437,7 +437,7 @@ For information about bearer access token propagation to the downstream services If introspection of the Bearer token is necessary, then `OidcProviderClient` must authenticate to the OIDC provider. For more information about supported authentication options, see the xref:security-oidc-code-flow-authentication.adoc#oidc-provider-client-authentication[OIDC provider client authentication] section in the Quarkus "OpenID Connect authorization code flow mechanism for protecting web applications" guide. -[[integration-testing]] +[[bearer-token-integration-testing]] === Testing [NOTE] @@ -469,7 +469,8 @@ testImplementation("io.rest-assured:rest-assured") testImplementation("io.quarkus:quarkus-junit5") ---- -[[integration-testing-wiremock]] +ifndef::no-deprecated-test-resource[] +[[bearer-token-integration-testing-wiremock]] ==== WireMock Add the following dependencies to your test project: @@ -589,6 +590,7 @@ public class CustomOidcWireMockStubTest { } } ---- +endif::no-deprecated-test-resource[] [[integration-testing-oidc-test-client]] === `OidcTestClient` @@ -604,7 +606,8 @@ For example, you have the following configuration: %test.quarkus.oidc.credentials.secret=secret ---- -To start, add the same dependency, `quarkus-test-oidc-server`, as described in the <> section. +ifndef::no-deprecated-test-resource[] +To start, add the same dependency, `quarkus-test-oidc-server`, as described in the <> section. Next, write the test code as follows: @@ -655,8 +658,9 @@ This test code acquires a token by using a `password` grant from the test `Auth0 For a test like this to work, the test `Auth0` application must have the `password` grant enabled. This example code also shows how to pass additional parameters. For `Auth0`, these are the `audience` and `scope` parameters. +endif::no-deprecated-test-resource[] -[[integration-testing-keycloak-devservices]] +[[bearer-token-integration-testing-keycloak-devservices]] ==== Dev Services for Keycloak The preferred approach for integration testing against Keycloak is xref:security-openid-connect-dev-services.adoc[Dev Services for Keycloak]. @@ -751,14 +755,14 @@ public class NativeBearerTokenAuthenticationIT extends BearerTokenAuthentication For more information about initializing and configuring Dev Services for Keycloak, see the xref:security-openid-connect-dev-services.adoc[Dev Services for Keycloak] guide. ifndef::no-deprecated-test-resource[] -[[integration-testing-keycloak]] +[[bearer-token-integration-testing-keycloak]] ==== `KeycloakTestResourceLifecycleManager` You can also use `KeycloakTestResourceLifecycleManager` for integration testing with Keycloak. [IMPORTANT] ==== -Use <> instead of `KeycloakTestResourceLifecycleManager` for integration testing with Keycloak, unless you have specific requirements for using `KeycloakTestResourceLifecycleManager`. +Use <> instead of `KeycloakTestResourceLifecycleManager` for integration testing with Keycloak, unless you have specific requirements for using `KeycloakTestResourceLifecycleManager`. ==== First, add the following dependency: @@ -868,13 +872,15 @@ quarkus.oidc.public-key=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlivFI8qB4D0y smallrye.jwt.sign.key.location=/privateKey.pem ---- -To generate JWT tokens, copy `privateKey.pem` from the `integration-tests/oidc-tenancy` in the `main` Quarkus repository and use a test code similar to the one in the preceding <> section. +ifndef::no-deprecated-test-resource[] +To generate JWT tokens, copy `privateKey.pem` from the `integration-tests/oidc-tenancy` in the `main` Quarkus repository and use a test code similar to the one in the preceding <> section. You can use your own test keys, if preferred. This approach provides limited coverage compared to the WireMock approach. For example, the remote communication code is not covered. +endif::no-deprecated-test-resource[] -[[integration-testing-security-annotation]] +[[bearer-token-integration-testing-security-annotation]] ==== TestSecurity annotation You can use `@TestSecurity` and `@OidcSecurity` annotations to test the `service` application endpoint code, which depends on either one, or all three, of the following injections: @@ -1234,11 +1240,11 @@ xref:security-openid-connect-multitenancy.adoc#tenant-config-resolver[Dynamic te Authentication that requires a dynamic tenant will fail. ==== -[[oidc-request-filters]] +[[bearer-token-oidc-request-filters]] == OIDC request filters You can filter OIDC requests made by Quarkus to the OIDC provider by registering one or more `OidcRequestFilter` implementations, which can update or add new request headers, and log requests. -For more information, see xref:security-oidc-code-flow-authentication#oidc-request-filters[OIDC request filters]. +For more information, see xref:security-oidc-code-flow-authentication#code-flow-oidc-request-filters[OIDC request filters]. == References diff --git a/docs/src/main/asciidoc/security-oidc-code-flow-authentication-tutorial.adoc b/docs/src/main/asciidoc/security-oidc-code-flow-authentication-tutorial.adoc index 05e2d54bd798d..3119501cdbea0 100644 --- a/docs/src/main/asciidoc/security-oidc-code-flow-authentication-tutorial.adoc +++ b/docs/src/main/asciidoc/security-oidc-code-flow-authentication-tutorial.adoc @@ -257,11 +257,11 @@ After clicking the `Login` button, you are redirected back to the application, a The session for this demo is valid for a short period of time and, on every page refresh, you will be asked to re-authenticate. For information about how to increase the session timeouts, see the Keycloak https://www.keycloak.org/docs/latest/server_admin/#_timeouts[session timeout] documentation. -For example, you can access the Keycloak Admin console directly from the dev UI by clicking the `Keycloak Admin` link if you use xref:security-oidc-code-flow-authentication.adoc#integration-testing-keycloak-devservices[Dev Services for Keycloak] in dev mode: +For example, you can access the Keycloak Admin console directly from the dev UI by clicking the `Keycloak Admin` link if you use xref:security-oidc-code-flow-authentication.adoc#code-flow-integration-testing-keycloak-devservices[Dev Services for Keycloak] in dev mode: image::dev-ui-oidc-keycloak-card.png[alt=Dev UI OpenID Connect Card,role="center"] -For more information about writing the integration tests that depend on `Dev Services for Keycloak`, see the xref:security-oidc-code-flow-authentication.adoc#integration-testing-keycloak-devservices[Dev Services for Keycloak] section. +For more information about writing the integration tests that depend on `Dev Services for Keycloak`, see the xref:security-oidc-code-flow-authentication.adoc#code-flow-integration-testing-keycloak-devservices[Dev Services for Keycloak] section. :sectnums!: diff --git a/docs/src/main/asciidoc/security-oidc-code-flow-authentication.adoc b/docs/src/main/asciidoc/security-oidc-code-flow-authentication.adoc index 40f43774f43cf..16338e8724505 100644 --- a/docs/src/main/asciidoc/security-oidc-code-flow-authentication.adoc +++ b/docs/src/main/asciidoc/security-oidc-code-flow-authentication.adoc @@ -295,7 +295,7 @@ quarkus.oidc.introspection-credentials.name=introspection-user-name quarkus.oidc.introspection-credentials.secret=introspection-user-secret ---- -[[oidc-request-filters]] +[[code-flow-oidc-request-filters]] ==== OIDC request filters You can filter OIDC requests made by Quarkus to the OIDC provider by registering one or more `OidcRequestFilter` implementations, which can update or add new request headers and can also log requests. @@ -492,7 +492,7 @@ Injection of the `JsonWebToken` and `AccessTokenCredential` is supported in both Quarkus OIDC uses the refresh token to refresh the current ID and access tokens as part of its <> process. -[[user-info]] +[[code-flow-user-info]] ==== User info If the ID token does not provide enough information about the currently authenticated user, you can get more information from the `UserInfo` endpoint. @@ -501,7 +501,7 @@ Set the `quarkus.oidc.authentication.user-info-required=true` property to reques A request is sent to the OIDC provider `UserInfo` endpoint by using the access token returned with the authorization code grant response, and an `io.quarkus.oidc.UserInfo` (a simple `jakarta.json.JsonObject` wrapper) object is created. `io.quarkus.oidc.UserInfo` can be injected or accessed as a SecurityIdentity `userinfo` attribute. -[[config-metadata]] +[[code-flow-config-metadata]] ==== Accessing the OIDC configuration information The current tenant's discovered link:https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata[OpenID Connect configuration metadata] is represented by `io.quarkus.oidc.OidcConfigurationMetadata` and can be injected or accessed as a `SecurityIdentity` `configuration-metadata` attribute. @@ -535,11 +535,11 @@ You can also map `SecurityIdentity` roles created from token claims to deploymen A core part of the authentication process is ensuring the chain of trust and validity of the information. This is done by ensuring tokens can be trusted. -[[token-verification-introspection]] +[[code-flow-token-verification-introspection]] ==== Token verification and introspection The verification process of OIDC authorization code flow tokens follows the Bearer token authentication token verification and introspection logic. -For more information, see the xref:security-oidc-bearer-token-authentication.adoc#token-verification-introspection[Token verification and introspection] section of the "Quarkus OpenID Connect (OIDC) Bearer token authentication" guide. +For more information, see the xref:security-oidc-bearer-token-authentication.adoc#bearer-token-token-verification-introspection[Token verification and introspection] section of the "Quarkus OpenID Connect (OIDC) Bearer token authentication" guide. [NOTE] ==== @@ -547,19 +547,19 @@ With Quarkus `web-app` applications, only the `IdToken` is verified by default b If you expect the access token to contain the roles required to access the current Quarkus endpoint (`quarkus.oidc.roles.source=accesstoken`), then it will also be verified. ==== -[[token-introspection-userinfo-cache]] +[[code-flow-token-introspection-userinfo-cache]] ==== Token introspection and UserInfo cache Code flow access tokens are not introspected unless they are expected to be the source of roles. However, they will be used to get `UserInfo`. There will be one or two remote calls with the code flow access token if the token introspection, `UserInfo`, or both are required. -For more information about using the default token cache or registering a custom cache implementation, see xref:security-oidc-bearer-token-authentication.adoc#token-introspection-userinfo-cache[Token introspection and UserInfo cache]. +For more information about using the default token cache or registering a custom cache implementation, see xref:security-oidc-bearer-token-authentication.adoc#bearer-token-token-introspection-userinfo-cache[Token introspection and UserInfo cache]. -[[jwt-claim-verification]] +[[code-flow-jwt-claim-verification]] ==== JSON web token claim verification -For information about the claim verification, including the `iss` (issuer) claim, see the xref:security-oidc-bearer-token-authentication.adoc#jwt-claim-verification[JSON Web Token claim verification] section. +For information about the claim verification, including the `iss` (issuer) claim, see the xref:security-oidc-bearer-token-authentication.adoc#bearer-token-jwt-claim-verification[JSON Web Token claim verification] section. It applies to ID tokens and also to access tokens in a JWT format, if the `web-app` application has requested the access token verification. ==== Further security with Proof Key for Code Exchange (PKCE) @@ -613,7 +613,7 @@ For example, to set the cookie path dynamically by using the value of the`X-Forw If `quarkus.oidc.authentication.cookie-path-header` is set but no configured HTTP header is available in the current request, then the `quarkus.oidc.authentication.cookie-path` will be checked. If your application is deployed across multiple domains, set the `quarkus.oidc.authentication.cookie-domain` property so that the session cookie is visible to all protected Quarkus services. -For example, if you have Quarkus services deployed on the following two domains, then you must set the `quarkus.oidc.authentication.cookie-domain` property to `company.net`. +For example, if you have Quarkus services deployed on the following two domains, then you must set the `quarkus.oidc.authentication.cookie-domain` property to `company.net`: * \https://whatever.wherever.company.net/ * \https://another.address.company.net/ @@ -866,13 +866,13 @@ Let's start with explicit logout operations. ===== User-initiated logout Users can request a logout by sending a request to the Quarkus endpoint logout path set with a `quarkus.oidc.logout.path` property. -For example, if the endpoint address is `https://application.com/webapp` and the `quarkus.oidc.logout.path` is set to "/logout", then the logout request must be sent to `https://application.com/webapp/logout`. +For example, if the endpoint address is `https://application.com/webapp` and the `quarkus.oidc.logout.path` is set to `/logout`, then the logout request must be sent to `https://application.com/webapp/logout`. This logout request starts an https://openid.net/specs/openid-connect-session-1_0.html#RPLogout[RP-initiated logout]. The user will be redirected to the OIDC provider to log out, where they can be asked to confirm the logout is indeed intended. The user will be returned to the endpoint post-logout page once the logout has been completed and if the `quarkus.oidc.logout.post-logout-path` property is set. -For example, if the endpoint address is `https://application.com/webapp` and the `quarkus.oidc.logout.post-logout-path` is set to "/signin", then the user will be returned to `https://application.com/webapp/signin`. +For example, if the endpoint address is `https://application.com/webapp` and the `quarkus.oidc.logout.post-logout-path` is set to `/signin`, then the user will be returned to `https://application.com/webapp/signin`. Note, this URI must be registered as a valid `post_logout_redirect_uri` in the OIDC provider. If the `quarkus.oidc.logout.post-logout-path` is set, then a `q_post_logout` cookie will be created and a matching `state` query parameter will be added to the logout redirect URI and the OIDC provider will return this `state` once the logout has been completed. @@ -1095,7 +1095,7 @@ This `access` token represents an authenticated user authorizing the current Qua For OIDC, you validate the ID token as proof of authentication validity whereas in the case of OAuth2, you validate the access token. This is done by subsequently calling an endpoint that requires the access token and that typically returns user information. -This approach is similar to the OIDC <> approach, with `UserInfo` fetched by Quarkus OIDC on your behalf. +This approach is similar to the OIDC <> approach, with `UserInfo` fetched by Quarkus OIDC on your behalf. For example, when working with GitHub, the Quarkus endpoint can acquire an `access` token, which allows the Quarkus endpoint to request a GitHub profile for the current user. @@ -1113,16 +1113,16 @@ This simplifies how you handle an application that supports multiple OIDC provid The next step is to ensure that the returned access token can be useful and is valid to the current Quarkus endpoint. The first way is to call the OAuth2 provider introspection endpoint by configuring `quarkus.oidc.introspection-path`, if the provider offers such an endpoint. In this case, you can use the access token as a source of roles using `quarkus.oidc.roles.source=accesstoken`. -If no introspection endpoint is present, you can attempt instead to request <> from the provider as it will at least validate the access token. +If no introspection endpoint is present, you can attempt instead to request <> from the provider as it will at least validate the access token. To do so, specify `quarkus.oidc.token.verify-access-token-with-user-info=true`. You also need to set the `quarkus.oidc.user-info-path` property to a URL endpoint that fetches the user info (or to an endpoint protected by the access token). For GitHub, since it does not have an introspection endpoint, requesting the UserInfo is required. [NOTE] ==== -Requiring <> involves making a remote call on every request. +Requiring <> involves making a remote call on every request. Therefore, you might want to consider caching `UserInfo` data. -For more information, see the xref:security-oidc-bearer-token-authentication.adoc#token-introspection-userinfo-cache[Token Introspection and UserInfo cache] section of the "OpenID Connect (OIDC) Bearer token authentication" guide. +For more information, see the xref:security-oidc-bearer-token-authentication.adoc#bearer-token-token-introspection-userinfo-cache[Token Introspection and UserInfo cache] section of the "OpenID Connect (OIDC) Bearer token authentication" guide. Alternatively, you might want to request that `UserInfo` is embedded into the internal generated `IdToken` with the `quarkus.oidc.cache-user-info-in-idtoken=true` property. The advantage of this approach is that, by default, no cached `UserInfo` state will be kept with the endpoint - instead it will be stored in a session cookie. @@ -1367,6 +1367,7 @@ Future callQuarkusService() async { If you plan to consume this application from a single-page application running on a different domain, you need to configure cross-origin resource sharing (CORS). For more information, see the xref:security-cors.adoc#cors-filter[CORS filter] section of the "Cross-origin resource sharing" guide. +ifndef::no-other-unproductized-features[] === Calling Cloud provider services ==== Google Cloud @@ -1402,6 +1403,7 @@ quarkus.oidc.client-id={GOOGLE_CLIENT_ID} quarkus.oidc.credentials.secret={GOOGLE_CLIENT_SECRET} quarkus.oidc.token.issuer=https://accounts.google.com ---- +endif::no-other-unproductized-features[] === Running Quarkus application behind a reverse proxy @@ -1486,7 +1488,7 @@ Then, you are ready to start authenticating your Quarkus users to the Okta SAML You can configure other OIDC providers to provide a SAML bridge similarly to how it can be done for Keycloak. -[[integration-testing]] +[[code-flow-integration-testing]] == Testing Testing is often tricky when it comes to authentication to a separate OIDC-like server. @@ -1523,7 +1525,7 @@ testImplementation("io.quarkus:quarkus-junit5") ---- ifndef::no-deprecated-test-resource[] -[[integration-testing-wiremock]] +[[code-flow-integration-testing-wiremock]] === Wiremock Add the following dependency: @@ -1611,7 +1613,7 @@ Additionally, `OidcWiremockTestResource` sets the token issuer and audience to ` `OidcWiremockTestResource` can be used to emulate all OIDC providers. endif::no-deprecated-test-resource[] -[[integration-testing-keycloak-devservices]] +[[code-flow-integration-testing-keycloak-devservices]] === Dev Services for Keycloak Using xref:security-openid-connect-dev-services.adoc[Dev Services for Keycloak] is recommended for integration testing against Keycloak. @@ -1636,7 +1638,8 @@ If a custom realm file has to be imported into Keycloak before running the tests quarkus.keycloak.devservices.realm-path=quarkus-realm.json ---- -Finally, write a test code the same way as it is described in the <> section. +ifndef::no-deprecated-test-resource[] +Finally, write a test code the same way as it is described in the <> section. The only difference is that `@QuarkusTestResource` is no longer needed: [source, java] @@ -1645,13 +1648,14 @@ The only difference is that `@QuarkusTestResource` is no longer needed: public class CodeFlowAuthorizationTest { } ---- +endif::no-deprecated-test-resource[] ifndef::no-deprecated-test-resource[] -[[integration-testing-keycloak]] +[[code-flow-integration-testing-keycloak]] === Using KeycloakTestResourceLifecycleManager Use `KeycloakTestResourceLifecycleManager` for your tests only if there is a good reason not to use `Dev Services for Keycloak`. -If you need to do the integration testing against Keycloak then you are encouraged to do it with <>. +If you need to do the integration testing against Keycloak then you are encouraged to do it with <>. First, add the following dependency: @@ -1692,7 +1696,7 @@ Then, configure the Maven Surefire plugin as follows (and similarly the Maven Fa ---- -Now, set the configuration and write the test code the same way as it is described in the <> section. +Now, set the configuration and write the test code the same way as it is described in the <> section. The only difference is the name of `QuarkusTestResource`: [source, java] @@ -1713,7 +1717,7 @@ By default, `KeycloakTestResourceLifecycleManager` uses HTTPS to initialize a Ke The default realm name is `quarkus` and client id is `quarkus-web-app` - set `keycloak.realm` and `keycloak.web-app.client` system properties to customize the values if needed. endif::no-deprecated-test-resource[] -[[integration-testing-security-annotation]] +[[code-flow-integration-testing-security-annotation]] === TestSecurity annotation You can use @TestSecurity and @OidcSecurity annotations to test the `web-app` application endpoint code, which depends on either one of the following injections, or all four: @@ -1723,7 +1727,7 @@ You can use @TestSecurity and @OidcSecurity annotations to test the `web-app` ap * `UserInfo` * `OidcConfigurationMetadata` -For more information, see xref:security-oidc-bearer-token-authentication.adoc#integration-testing-security-annotation[Use TestingSecurity with injected JsonWebToken]. +For more information, see xref:security-oidc-bearer-token-authentication.adoc#bearer-token-integration-testing-security-annotation[Use TestingSecurity with injected JsonWebToken]. === Checking errors in the logs diff --git a/docs/src/main/asciidoc/security-openid-connect-client-reference.adoc b/docs/src/main/asciidoc/security-openid-connect-client-reference.adoc index acd8627a157fe..a04aaca23802c 100644 --- a/docs/src/main/asciidoc/security-openid-connect-client-reference.adoc +++ b/docs/src/main/asciidoc/security-openid-connect-client-reference.adoc @@ -768,7 +768,8 @@ Start by adding the following dependencies to your test project: ---- -[[integration-testing-wiremock]] +ifndef::no-deprecated-test-resource[] +[[oidc-client-ref-integration-testing-wiremock]] ==== Wiremock Add the following dependencies to your test project: @@ -857,10 +858,11 @@ quarkus.oidc-client.grant-options.password.password=alice ---- And finally, write the test code. Given the Wiremock-based resource above, the first test invocation should return the `access_token_1` access token, which will expire in 4 seconds. Use `awaitility` to wait for about 5 seconds, and now the next test invocation should return the `access_token_2` access token, which confirms the expired `access_token_1` access token has been refreshed. +endif::no-deprecated-test-resource[] ==== Keycloak -If you work with Keycloak, you can use the same approach described in the xref:security-oidc-bearer-token-authentication.adoc#integration-testing-keycloak[OpenID Connect Bearer Token Integration testing] Keycloak section. +If you work with Keycloak, you can use the same approach described in the xref:security-oidc-bearer-token-authentication.adoc#bearer-token-integration-testing-keycloak[OpenID Connect Bearer Token Integration testing] Keycloak section. === How to check the errors in the logs @@ -880,7 +882,7 @@ quarkus.log.category."io.quarkus.oidc.client.runtime.OidcClientRecorder".level=T quarkus.log.category."io.quarkus.oidc.client.runtime.OidcClientRecorder".min-level=TRACE ---- -[[oidc-request-filters]] +[[oidc-client-ref-oidc-request-filters]] == OIDC request filters You can filter OIDC requests made by Quarkus to the OIDC provider by registering one or more `OidcRequestFilter` implementations, which can update or add new request headers. For example, a filter can analyze the request body and add its digest as a new header value: @@ -1149,7 +1151,7 @@ As mentioned, use `AccessTokenRequestFilter` if you work with Keycloak or an Ope [[integration-testing-token-propagation]] === Testing -You can generate the tokens as described in xref:security-oidc-bearer-token-authentication.adoc#integration-testing[OpenID Connect Bearer Token Integration testing] section. +You can generate the tokens as described in xref:security-oidc-bearer-token-authentication.adoc#bearer-token-integration-testing[OpenID Connect Bearer Token Integration testing] section. Prepare the REST test endpoints. You can have the test front-end endpoint, which uses the injected MP REST client with a registered token propagation filter, call the downstream endpoint. For example, see the `integration-tests/oidc-token-propagation` in the `main` Quarkus repository. ifndef::no-quarkus-oidc-token-propagation[] diff --git a/docs/src/main/asciidoc/security-openid-connect-client.adoc b/docs/src/main/asciidoc/security-openid-connect-client.adoc index 5453c97f55663..682b412c56094 100644 --- a/docs/src/main/asciidoc/security-openid-connect-client.adoc +++ b/docs/src/main/asciidoc/security-openid-connect-client.adoc @@ -393,12 +393,12 @@ This configuration references Keycloak, which is used by `ProtectedResource` to Both REST clients point to `ProtectedResource`'s HTTP address. NOTE: Adding a `%prod.` profile prefix to `quarkus.oidc.auth-server-url` ensures that `Dev Services for Keycloak` launches a container for you when the application is run in dev or test modes. -For more information, see the <> section. +For more information, see the <> section. == Starting and configuring the Keycloak server NOTE: Do not start the Keycloak server when you run the application in dev or test modes; `Dev Services for Keycloak` launches a container. -For more information, see the <> section. +For more information, see the <> section. Ensure you put the link:{quickstarts-tree-url}/security-openid-connect-client-quickstart/config/quarkus-realm.json[realm configuration file] on the classpath, in the `target/classes` directory. This placement ensures that the file is automatically imported in dev mode. However, if you have already built a link:{quickstarts-tree-url}/security-openid-connect-quickstart[complete solution], you do not need to add the realm file to the classpath because the build process has already done so. @@ -424,7 +424,7 @@ This `quarkus` realm file adds a `frontend` client, and `alice` and `admin` user `alice` has a `user` role. `admin` has both `user` and `admin` roles. -[[keycloak-dev-mode]] +[[oidc-client-keycloak-dev-mode]] == Running the application in dev mode To run the application in a dev mode, use: @@ -485,7 +485,7 @@ After a little while, when the build finishes, you can run the native binary dir == Testing the application -For more information about testing your application in dev mode, see the preceding <> section. +For more information about testing your application in dev mode, see the preceding <> section. You can test the application launched in JVM or Native modes with `curl`. diff --git a/docs/src/main/asciidoc/security-openid-connect-dev-services.adoc b/docs/src/main/asciidoc/security-openid-connect-dev-services.adoc index 32ebe11900fc0..57e38f81953f0 100644 --- a/docs/src/main/asciidoc/security-openid-connect-dev-services.adoc +++ b/docs/src/main/asciidoc/security-openid-connect-dev-services.adoc @@ -253,7 +253,7 @@ The OIDC Dev UI is also more beneficial because hybrid applications can also acc You can run the tests against a Keycloak container started in a test mode in a xref:continuous-testing.adoc[Continuous Testing] mode. It is also recommended to run the integration tests against Keycloak by using Dev Services for Keycloak. -For more information, see xref:security-oidc-bearer-token-authentication.adoc#integration-testing-keycloak-devservices[Testing OpenID Connect Service Applications with Dev Services] and xref:security-oidc-code-flow-authentication.adoc#integration-testing-keycloak-devservices[Testing OpenID Connect WebApp Applications with Dev Services]. +For more information, see xref:security-oidc-bearer-token-authentication.adoc#bearer-token-integration-testing-keycloak-devservices[Testing OpenID Connect Service Applications with Dev Services] and xref:security-oidc-code-flow-authentication.adoc#code-flow-integration-testing-keycloak-devservices[Testing OpenID Connect WebApp Applications with Dev Services]. [[keycloak-initialization]] === Keycloak initialization diff --git a/docs/src/main/asciidoc/security-testing.adoc b/docs/src/main/asciidoc/security-testing.adoc index 382087d19aa46..fbd6e88351f77 100644 --- a/docs/src/main/asciidoc/security-testing.adoc +++ b/docs/src/main/asciidoc/security-testing.adoc @@ -91,7 +91,7 @@ This will run the test with an identity with the given username and roles. Note disable authorization while also providing an identity to run the test under, which can be useful if the endpoint expects an identity to be present. -See xref:security-oidc-bearer-token-authentication.adoc#integration-testing-security-annotation[OpenID Connect Bearer Token Integration testing], xref:security-oidc-code-flow-authentication.adoc#integration-testing-security-annotation[OpenID Connect Authorization Code Flow Integration testing] and xref:security-jwt.adoc#integration-testing-security-annotation[SmallRye JWT Integration testing] for more details about testing the endpoint code which depends on the injected `JsonWebToken`. +See xref:security-oidc-bearer-token-authentication.adoc#bearer-token-integration-testing-security-annotation[OpenID Connect Bearer Token Integration testing], xref:security-oidc-code-flow-authentication.adoc#code-flow-integration-testing-security-annotation[OpenID Connect Authorization Code Flow Integration testing] and xref:security-jwt.adoc#integration-testing-security-annotation[SmallRye JWT Integration testing] for more details about testing the endpoint code which depends on the injected `JsonWebToken`. [WARNING] ==== @@ -124,7 +124,7 @@ for example by setting `quarkus.http.auth.basic=true` or `%test.quarkus.http.aut == Use Wiremock for Integration Testing You can also use Wiremock to mock the authorization OAuth2 and OIDC services: -See xref:security-oauth2.adoc#integration-testing[OAuth2 Integration testing], xref:security-oidc-bearer-token-authentication.adoc#integration-testing-wiremock[OpenID Connect Bearer Token Integration testing], xref:security-oidc-code-flow-authentication.adoc#integration-testing-wiremock[OpenID Connect Authorization Code Flow Integration testing] and xref:security-jwt.adoc#integration-testing-wiremock[SmallRye JWT Integration testing] for more details. +See xref:security-oauth2.adoc#integration-testing[OAuth2 Integration testing], xref:security-oidc-bearer-token-authentication.adoc#bearer-token-integration-testing-wiremock[OpenID Connect Bearer Token Integration testing], xref:security-oidc-code-flow-authentication.adoc#code-flow-integration-testing-wiremock[OpenID Connect Authorization Code Flow Integration testing] and xref:security-jwt.adoc#integration-testing-wiremock[SmallRye JWT Integration testing] for more details. == References