From c7ac420a0c913061253fa522563cce51da05319c Mon Sep 17 00:00:00 2001 From: Georgios Andrianakis Date: Tue, 4 Jan 2022 16:41:32 +0200 Subject: [PATCH] Use proper casing when referring to OpenID Connect in docs --- docs/src/main/asciidoc/security-jwt.adoc | 10 ++-- .../security-keycloak-authorization.adoc | 6 +-- docs/src/main/asciidoc/security-oauth2.adoc | 4 +- .../security-openid-connect-client.adoc | 24 ++++----- .../security-openid-connect-dev-services.adoc | 54 +++++++++---------- .../security-openid-connect-multitenancy.adoc | 4 +- ...ity-openid-connect-web-authentication.adoc | 40 +++++++------- .../asciidoc/security-openid-connect.adoc | 38 ++++++------- docs/src/main/asciidoc/security-testing.adoc | 4 +- docs/src/main/asciidoc/security.adoc | 22 ++++---- 10 files changed, 103 insertions(+), 103 deletions(-) diff --git a/docs/src/main/asciidoc/security-jwt.adoc b/docs/src/main/asciidoc/security-jwt.adoc index 0fb27ab802e52..b69cf05cb46e1 100644 --- a/docs/src/main/asciidoc/security-jwt.adoc +++ b/docs/src/main/asciidoc/security-jwt.adoc @@ -13,8 +13,8 @@ This guide explains how your Quarkus application can utilize https://github.com/ to verify https://tools.ietf.org/html/rfc7519[JSON Web Token]s, represent them as MicroProfile JWT `org.eclipse.microprofile.jwt.JsonWebToken` and provide secured access to the Quarkus HTTP endpoints using Bearer Token Authorization and https://en.wikipedia.org/wiki/Role-based_access_control[Role-Based Access Control]. -NOTE: Quarkus OpenId Connect `quarkus-oidc` extension also supports Bearer Token Authorization and uses `smallrye-jwt` to represent the bearer tokens as `JsonWebToken`, please read the xref:security-openid-connect.adoc[Using OpenID Connect to Protect Service Applications] guide for more information. -OpenId Connect extension has to be used if the Quarkus application needs to authenticate the users using OIDC Authorization Code Flow, please read xref:security-openid-connect-web-authentication.adoc[Using OpenID Connect to Protect Web Applications] guide for more information. +NOTE: Quarkus OpenID Connect `quarkus-oidc` extension also supports Bearer Token Authorization and uses `smallrye-jwt` to represent the bearer tokens as `JsonWebToken`, please read the xref:security-openid-connect.adoc[Using OpenID Connect to Protect Service Applications] guide for more information. +OpenID Connect extension has to be used if the Quarkus application needs to authenticate the users using OIDC Authorization Code Flow, please read xref:security-openid-connect-web-authentication.adoc[Using OpenID Connect to Protect Web Applications] guide for more information. == Quickstart @@ -814,7 +814,7 @@ Please see xref:security-openid-connect-client.adoc#token-propagation[Token Prop [[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-openid-connect.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-openid-connect.adoc#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] ---- @@ -826,7 +826,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-openid-connect.adoc#integration-testing-keycloak[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-openid-connect.adoc#integration-testing-keycloak[OpenID Connect Bearer Token Integration testing] `Keycloak` section but only change the `application.properties` to use MP JWT configuration properties instead: [source, properties] ---- @@ -838,7 +838,7 @@ mp.jwt.verify.issuer=${keycloak.url}/realms/quarkus [[integration-testing-public-key]] ==== Local Public Key -You can use the same approach as described in the xref:security-openid-connect#integration-testing.adoc[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-openid-connect#integration-testing.adoc[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-keycloak-authorization.adoc b/docs/src/main/asciidoc/security-keycloak-authorization.adoc index 2671e6ac2b43b..33ff957ee6c22 100644 --- a/docs/src/main/asciidoc/security-keycloak-authorization.adoc +++ b/docs/src/main/asciidoc/security-keycloak-authorization.adoc @@ -227,9 +227,9 @@ It explains why the endpoint has no `@RolesAllowed` annotations - the resource a To run the application in dev mode, use `./mvnw clean compile quarkus:dev`. xref:security-openid-connect-dev-services.adoc[Dev Services for Keycloak] will launch a Keycloak container and import a `quarkus-realm.json`. -Open a xref:dev-ui.adoc[Dev UI] available at http://localhost:8080/q/dev[/q/dev] and click on a `Provider: Keycloak` link in an `OpenId Connect` `Dev UI` card. +Open a xref:dev-ui.adoc[Dev UI] available at http://localhost:8080/q/dev[/q/dev] and click on a `Provider: Keycloak` link in an `OpenID Connect` `Dev UI` card. -You will be asked to login into a `Single Page Application` provided by `OpenId Connect Dev UI`: +You will be asked to login into a `Single Page Application` provided by `OpenID Connect Dev UI`: * Login as `alice` (password: `alice`) who only has a `User Permission` to access the `/api/users/me` resource ** accessing `/api/admin` will return `403` @@ -418,7 +418,7 @@ Note only the default tenant configuration applies when controlling an anonymous == Multi-Tenancy -It is possible to configure multiple policy enforcer configurations, one per each tenant, similarly to how it can be done for xref:security-openid-connect-multitenancy.adoc[Multi-Tenant OpenId Connect Service Applications]. +It is possible to configure multiple policy enforcer configurations, one per each tenant, similarly to how it can be done for xref:security-openid-connect-multitenancy.adoc[Multi-Tenant OpenID Connect Service Applications]. For example: diff --git a/docs/src/main/asciidoc/security-oauth2.adoc b/docs/src/main/asciidoc/security-oauth2.adoc index f9455c14de1f6..08f6f58534247 100644 --- a/docs/src/main/asciidoc/security-oauth2.adoc +++ b/docs/src/main/asciidoc/security-oauth2.adoc @@ -16,8 +16,8 @@ It can be used to implement an application authentication mechanism based on tok This extension provides a light-weight support for using the opaque Bearer Tokens and validating them by calling an introspection endpoint. -If the OAuth2 Authentication server provides JWT Bearer Tokens then you should consider using either xref:security-openid-connect.adoc[OpenId Connect] or xref:security-jwt.adoc[SmallRye JWT] extensions instead. -OpenId Connect extension has to be used if the Quarkus application needs to authenticate the users using OIDC Authorization Code Flow, please read xref:security-openid-connect-web-authentication.adoc[Using OpenID Connect to Protect Web Applications] guide for more information. +If the OAuth2 Authentication server provides JWT Bearer Tokens then you should consider using either xref:security-openid-connect.adoc[OpenID Connect] or xref:security-jwt.adoc[SmallRye JWT] extensions instead. +OpenID Connect extension has to be used if the Quarkus application needs to authenticate the users using OIDC Authorization Code Flow, please read xref:security-openid-connect-web-authentication.adoc[Using OpenID Connect to Protect Web Applications] guide for more information. include::./status-include.adoc[] diff --git a/docs/src/main/asciidoc/security-openid-connect-client.adoc b/docs/src/main/asciidoc/security-openid-connect-client.adoc index cefceffc6d7c2..1d6ce8261d093 100644 --- a/docs/src/main/asciidoc/security-openid-connect-client.adoc +++ b/docs/src/main/asciidoc/security-openid-connect-client.adoc @@ -10,7 +10,7 @@ include::./attributes.adoc[] This guide explains how to use: - - `quarkus-oidc-client`, `quarkus-oidc-client-reactive-filter` and `quarkus-oidc-client-filter` extensions to acquire and refresh access tokens from OpenId Connect and OAuth 2.0 compliant Authorization Servers such as https://www.keycloak.org/about.html[Keycloak] + - `quarkus-oidc-client`, `quarkus-oidc-client-reactive-filter` and `quarkus-oidc-client-filter` extensions to acquire and refresh access tokens from OpenID Connect and OAuth 2.0 compliant Authorization Servers such as https://www.keycloak.org/about.html[Keycloak] - `quarkus-oidc-token-propagation` extension to propagate the current `Bearer` or `Authorization Code Flow` access tokens The access tokens managed by these extensions can be used as HTTP Authorization Bearer tokens to access the remote services. @@ -124,7 +124,7 @@ and then you can use `OidcClient.refreshTokens` method with a provided refresh t Using the `token exchange` grant may be required if you are building a complex microservices application and would like to avoid the same `Bearer` token be propagated to and used by more than one service. Please see <> for more details. -Using `OidcClient` to support the `authorization code` grant might be required if for some reasons you can not use the xref:security-openid-connect-web-authentication.adoc[Quarkus OpenId Connect extension] to support Authorization Code Flow. If there is a very good reason for you to implement Authorization Code Flow then you can configure `OidcClient` as follows: +Using `OidcClient` to support the `authorization code` grant might be required if for some reasons you can not use the xref:security-openid-connect-web-authentication.adoc[Quarkus OpenID Connect extension] to support Authorization Code Flow. If there is a very good reason for you to implement Authorization Code Flow then you can configure `OidcClient` as follows: [source,properties] ---- @@ -491,12 +491,12 @@ Additionally, `quarkus.oidc-client.refresh-token-time-skew` property can be used If the access token needs to be refreshed but no refresh token is available then an attempt will be made to acquire a new token using the configured grant such as `client_credentials`. -Please note that some OpenId Connect Providers will not return a refresh token in a `client_credentials` grant response. For example, starting from Keycloak 12 a refresh token will not be returned by default for `client_credentials`. The providers may also restrict a number of times a refresh token can be used. +Please note that some OpenID Connect Providers will not return a refresh token in a `client_credentials` grant response. For example, starting from Keycloak 12 a refresh token will not be returned by default for `client_credentials`. The providers may also restrict a number of times a refresh token can be used. [[oidc-client-authentication]] === OidcClient Authentication -`OidcClient` has to authenticate to the OpenId Connect Provider for the `client_credentials` and other grant requests to succeed. +`OidcClient` has to authenticate to the OpenID Connect Provider for the `client_credentials` and other grant requests to succeed. All the https://openid.net/specs/openid-connect-core-1_0.html#ClientAuthentication[OIDC Client Authentication] options are supported, for example: `client_secret_basic`: @@ -599,7 +599,7 @@ quarkus.oidc-client.auth-server-url=http://localhost:8180/auth/realms/quarkus/ quarkus.oidc-client.client-id=quarkus-app quarkus.oidc-client.credentials.jwt.key-file=privateKey.pem -# This is a token key identifier 'kid' header - set it if your OpenId Connect provider requires it. +# This is a token key identifier 'kid' header - set it if your OpenID Connect provider requires it. # Note if the key is represented in a JSON Web Key (JWK) format with a `kid` property then # using 'quarkus.oidc-client.credentials.jwt.token-key-id' is not necessary. quarkus.oidc-client.credentials.jwt.token-key-id=mykey @@ -619,7 +619,7 @@ quarkus.oidc-client.credentials.jwt.issuer=custom-issuer ==== Apple POST JWT -Apple OpenId Connect Provider uses a `client_secret_post` method where a secret is a JWT produced with a `private_key_jwt` authentication method but with Apple account specific issuer and subject properties. +Apple OpenID Connect Provider uses a `client_secret_post` method where a secret is a JWT produced with a `private_key_jwt` authentication method but with Apple account specific issuer and subject properties. `quarkus-oidc-client` supports a non-standard `client_secret_post_jwt` authentication method which can be configured as follows: @@ -746,7 +746,7 @@ and finally write the test code. Given the Wiremock-based resource above, the fi ==== Keycloak -If you work with Keycloak then you can use the same approach as described in the xref:security-openid-connect#integration-testing-keycloak.adoc[OpenId Connect Bearer Token Integration testing] `Keycloak` section. +If you work with Keycloak then you can use the same approach as described in the xref:security-openid-connect#integration-testing-keycloak.adoc[OpenID Connect Bearer Token Integration testing] `Keycloak` section. === How to check the errors in the logs @@ -823,7 +823,7 @@ Alternatively, `AccessTokenRequestFilter` can be registered automatically with a ==== Exchange Token Before Propagation -If the current access token needs to be exchanged before propagation and you work with link:https://www.keycloak.org/docs/latest/securing_apps/#_token-exchange[Keycloak] or other OpenId Connect Provider which supports a link:https://tools.ietf.org/html/rfc8693[Token Exchange] token grant then you can configure `AccessTokenRequestFilter` like this: +If the current access token needs to be exchanged before propagation and you work with link:https://www.keycloak.org/docs/latest/securing_apps/#_token-exchange[Keycloak] or other OpenID Connect Provider which supports a link:https://tools.ietf.org/html/rfc8693[Token Exchange] token grant then you can configure `AccessTokenRequestFilter` like this: [source,properties] ---- @@ -836,13 +836,13 @@ quarkus.oidc-client.grant-options.exchange.audience=quarkus-app-exchange quarkus.oidc-token-propagation.exchange-token=true ---- -Note `AccessTokenRequestFilter` will use `OidcClient` to exchange the current token and you can use `quarkus.oidc-client.grant-options.exchange` to set the additional exchange properties expected by your OpenId Connect Provider. +Note `AccessTokenRequestFilter` will use `OidcClient` to exchange the current token and you can use `quarkus.oidc-client.grant-options.exchange` to set the additional exchange properties expected by your OpenID Connect Provider. `AccessTokenRequestFilter` uses a default `OidcClient` by default. A named `OidcClient` can be selected with a `quarkus.oidc-token-propagation.client-name` configuration property. === RestClient JsonWebTokenRequestFilter -Using `JsonWebTokenRequestFilter` is recommended if you work with Bearer JWT tokens where these tokens can have their claims such as `issuer` and `audience` modified and the updated tokens secured (for example, re-signed) again. It expects an injected `org.eclipse.microprofile.jwt.JsonWebToken` and therefore will not work with the opaque tokens. Also, if your OpenId Connect Provider supports a Token Exchange protocol then it is recommended to use `AccessTokenRequestFilter` instead - as both JWT and opaque bearer tokens can be securely exchanged with `AccessTokenRequestFilter`. +Using `JsonWebTokenRequestFilter` is recommended if you work with Bearer JWT tokens where these tokens can have their claims such as `issuer` and `audience` modified and the updated tokens secured (for example, re-signed) again. It expects an injected `org.eclipse.microprofile.jwt.JsonWebToken` and therefore will not work with the opaque tokens. Also, if your OpenID Connect Provider supports a Token Exchange protocol then it is recommended to use `AccessTokenRequestFilter` instead - as both JWT and opaque bearer tokens can be securely exchanged with `AccessTokenRequestFilter`. `JsonWebTokenRequestFilter` makes it easy for `Service A` implementations to update the injected `org.eclipse.microprofile.jwt.JsonWebToken` with the new `issuer` and `audience` claim values and secure the updated token again with a new signature. The only difficult step is to ensure `Service A` has a signing key - it should be provisioned from a secure file system or from the remote secure storage such as Vault. @@ -898,12 +898,12 @@ smallrye.jwt.new-token.audience=http://downstream-resource smallrye.jwt.new-token.override-matching-claims=true ---- -As already noted above, please use `AccessTokenRequestFilter` if you work with Keycloak or OpenId Connect Provider which supports a Token Exchange protocol. +As already noted above, please use `AccessTokenRequestFilter` if you work with Keycloak or OpenID Connect Provider which supports a Token Exchange protocol. [[integration-testing-token-propagation]] === Testing -You can generate the tokens as described in xref:security-openid-connect.adoc#integration-testing[OpenId Connect Bearer Token Integration testing] section. +You can generate the tokens as described in xref:security-openid-connect.adoc#integration-testing[OpenID Connect Bearer Token Integration testing] section. Prepare the REST test endpoints, you can have the test frontend endpoint which uses the injected MP REST client with a registered token propagation filter to invoke on the downstream endpoint, for example, see the `integration-tests/oidc-token-propagation` in the `main` Quarkus repository. == References 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 c69c83e21bb3f..d767446a7e7e2 100644 --- a/docs/src/main/asciidoc/security-openid-connect-dev-services.adoc +++ b/docs/src/main/asciidoc/security-openid-connect-dev-services.adoc @@ -3,12 +3,12 @@ This guide is maintained in the main Quarkus repository and pull requests should be submitted there: https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc //// -= Dev Services and UI for OpenId Connect (OIDC) += Dev Services and UI for OpenID Connect (OIDC) include::./attributes.adoc[] -This guide covers the Dev Services and UI for OpenId Connect (OIDC) Keycloak provider and explains how to support Dev Services and UI for other OpenId Connect providers. -It also describes Dev UI for all OpenId Connect providers which have already been started before Quarkus is launched in a dev mode. +This guide covers the Dev Services and UI for OpenID Connect (OIDC) Keycloak provider and explains how to support Dev Services and UI for other OpenID Connect providers. +It also describes Dev UI for all OpenID Connect providers which have already been started before Quarkus is launched in a dev mode. == Introduction @@ -17,7 +17,7 @@ It starts a Keycloak container for both the dev and/or test modes and initialize Additionally, xref:dev-ui.adoc[Dev UI] available at http://localhost:8080/q/dev[/q/dev] complements this feature with a Dev UI page which helps to acquire the tokens from Keycloak and test your Quarkus application. -If `quarkus.oidc.auth-server-url` is already set then a generic OpenId Connect Dev Console which can be used with all OpenId Connect providers will be activated, please see <> for more information. +If `quarkus.oidc.auth-server-url` is already set then a generic OpenID Connect Dev Console which can be used with all OpenID Connect providers will be activated, please see <> for more information. == Dev Services for Keycloak @@ -47,9 +47,9 @@ $ mvn quarkus:dev Note that you can disable sharing the containers with `quarkus.keycloak.devservices.shared=false`. -Now open the main link:http://localhost:8080/q/dev[Dev UI page] and you will see the `OpenId Connect Card` linking to a `Keycloak` page: +Now open the main link:http://localhost:8080/q/dev[Dev UI page] and you will see the `OpenID Connect Card` linking to a `Keycloak` page: -image::dev-ui-oidc-keycloak-card.png[alt=Dev UI OpenId Connect Card,role="center"] +image::dev-ui-oidc-keycloak-card.png[alt=Dev UI OpenID Connect Card,role="center"] Click on the `Provider: Keycloak` link and you will see a Keycloak page which will be presented slightly differently depending on how `Dev Services for Keycloak` feature has been configured. @@ -65,15 +65,15 @@ If you set `quarkus.oidc.devui.grant.type=code` in `application.properties` (thi First you will see an option to `Log into Single Page Application`: -image::dev-ui-keycloak-sign-in-to-spa.png[alt=Dev UI OpenId Connect Keycloak Page - Log into Single Page Application,role="center"] +image::dev-ui-keycloak-sign-in-to-spa.png[alt=Dev UI OpenID Connect Keycloak Page - Log into Single Page Application,role="center"] Next, after you select this option, you will be redirected to Keycloak to authenticate, example, as `alice:alice` and then returned to the page representing the SPA: -image::dev-ui-keycloak-test-service-from-spa.png[alt=Dev UI OpenId Connect Keycloak Single Page Application,role="center"] +image::dev-ui-keycloak-test-service-from-spa.png[alt=Dev UI OpenID Connect Keycloak Single Page Application,role="center"] You can view the acquired access and ID tokens, for example: -image::dev-ui-keycloak-decoded-tokens.png[alt=Dev UI OpenId Connect Keycloak Decoded Tokens View,role="center"] +image::dev-ui-keycloak-decoded-tokens.png[alt=Dev UI OpenID Connect Keycloak Decoded Tokens View,role="center"] This view shows the encoded JWT token on the left hand side and highlights the headers (red colour), payload/claims (green colour) and signature (blue colour). It also shows the decoded JWT token on the right hand side where you can see the header and claim names and their values. @@ -121,7 +121,7 @@ If you set `quarkus.oidc.devui.grant.type=implicit` in `application.properties` If you set `quarkus.oidc.devui.grant.type=password` in `application.properties` then you will see a screen like this one: -image::dev-ui-keycloak-password-grant.png[alt=Dev UI OpenId Connect Keycloak Page - Password Grant,role="center"] +image::dev-ui-keycloak-password-grant.png[alt=Dev UI OpenID Connect Keycloak Page - Password Grant,role="center"] Enter a registered user name, user password, a relative service endpoint path, click on `Test Service` and you will see a status code such as `200`, `403`, `401` or `404` printed. If the user name is also set in `quarkus.keycloak.devservices.users` map property containing user names and passwords then you do not have to set a password when testing the service. @@ -143,18 +143,18 @@ A token is acquired from Keycloak using a `password` grant and is sent to the se If you set `quarkus.oidc.devui.grant.type=client` then a `client_credentials` grant will be used to acquire a token, with the page showing no `User` field in this case: -image::dev-ui-keycloak-client-credentials-grant.png[alt=Dev UI OpenId Connect Keycloak Page - Client Credentials Grant,role="center"] +image::dev-ui-keycloak-client-credentials-grant.png[alt=Dev UI OpenID Connect Keycloak Page - Client Credentials Grant,role="center"] You can test the service the same way as with the `Password` grant. [[develop-web-app-applications]] -=== Developing OpenId Connect Web App Applications +=== Developing OpenID Connect Web App Applications If you develop a xref:security-openid-connect-web-authentication.adoc[Quarkus OIDC web-app application] then you should set `quarkus.oidc.application-type=web-app` in `application.properties` before starting the application. You will see a screen like this one: -image::dev-ui-keycloak-sign-in-to-service.png[alt=Dev UI OpenId Connect Keycloak Sign In,role="center"] +image::dev-ui-keycloak-sign-in-to-service.png[alt=Dev UI OpenID Connect Keycloak Sign In,role="center"] Set a relative service endpoint path, click on `Sign In To Service` and you will be redirected to Keycloak to enter a username and password in a new browser tab and get a response from the Quarkus application. @@ -169,7 +169,7 @@ To make Dev UI more useful for supporting the development of OIDC `web-app` appl %dev.quarkus.oidc.application-type=service ---- -It will ensure that all Dev UI options described in <> will be available when your `web-app` application is run in dev mode. The limitation of this approach is that both access and ID tokens returned with the code flow and acquired with Dev UI will be sent to the endpoint as HTTP `Bearer` tokens - which will not work well if your endpoint requires the injection of `IdToken`. +It will ensure that all Dev UI options described in <> will be available when your `web-app` application is run in dev mode. The limitation of this approach is that both access and ID tokens returned with the code flow and acquired with Dev UI will be sent to the endpoint as HTTP `Bearer` tokens - which will not work well if your endpoint requires the injection of `IdToken`. However it will work as expected if your `web-app` application only uses the access token, for example, as a source of roles or to get `UserInfo`, even if it is assumed to be a `service` application in devmode. === Running the tests @@ -177,7 +177,7 @@ However it will work as expected if your `web-app` application only uses the 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 using `Dev Services for Keycloak`. -Please see xref:security-openid-connect.adoc#integration-testing-keycloak-devservices[Testing OpenId Connect Service Applications with Dev Services] and xref:security-openid-connect-web-authentication.adoc#integration-testing-keycloak-devservices[Testing OpenId Connect WebApp Applications with Dev Services] for more information. +Please see xref:security-openid-connect.adoc#integration-testing-keycloak-devservices[Testing OpenID Connect Service Applications with Dev Services] and xref:security-openid-connect-web-authentication.adoc#integration-testing-keycloak-devservices[Testing OpenID Connect WebApp Applications with Dev Services] for more information. [[keycloak-initialization]] === Keycloak Initialization @@ -199,7 +199,7 @@ This is why `quarkus.keycloak.devservices.realm-path` is always checked first be Also the Keycloak page offers an option to `Sign In To Keycloak To Configure Realms` using a `Keycloak Admin` option in the right top corner: -image::dev-ui-keycloak-admin.png[alt=Dev UI OpenId Connect Keycloak Page - Keycloak Admin,role="center"] +image::dev-ui-keycloak-admin.png[alt=Dev UI OpenID Connect Keycloak Page - Keycloak Admin,role="center"] Sign in to Keycloak as `admin:admin` in order to further customize the realm properties, create or import a new realm, export the realm. @@ -211,19 +211,19 @@ Note that even if you initialize Keycloak from a realm file, it is still needed If you prefer not to have a `Dev Services for Keycloak` container started or do not work with Keycloak then you can also disable this feature with `quarkus.keycloak.devservices.enabled=false` - it will only be necessary if you expect to start `quarkus:dev` without `quarkus.oidc.auth-server-url`. -The main Dev UI page will include an empty `OpenId Connect Card` when `Dev Services for Keycloak` is disabled and the `quarkus.oidc.auth-server-url` property +The main Dev UI page will include an empty `OpenID Connect Card` when `Dev Services for Keycloak` is disabled and the `quarkus.oidc.auth-server-url` property has not been initialized: -image::dev-ui-oidc-card.png[alt=Dev UI OpenId Connect Card,role="center"] +image::dev-ui-oidc-card.png[alt=Dev UI OpenID Connect Card,role="center"] -If `quarkus.oidc.auth-server-url` is already set then a generic OpenId Connect Dev Console which can be used with all OpenId Connect providers may be activated, please see <> for more information. +If `quarkus.oidc.auth-server-url` is already set then a generic OpenID Connect Dev Console which can be used with all OpenID Connect providers may be activated, please see <> for more information. [[dev-ui-all-oidc-providers]] -== Dev UI for all OpenId Connect Providers +== Dev UI for all OpenID Connect Providers -If `quarkus.oidc.auth-server-url` points to an already started OpenId Connect provider (which can be Keycloak or other provider), `quarkus.oidc.auth-server-url` is set to `service` (which is a default value) and at least `quarkus.oidc.client-id` is set then `Dev UI for all OpenId Connect Providers` will be activated. +If `quarkus.oidc.auth-server-url` points to an already started OpenID Connect provider (which can be Keycloak or other provider), `quarkus.oidc.auth-server-url` is set to `service` (which is a default value) and at least `quarkus.oidc.client-id` is set then `Dev UI for all OpenID Connect Providers` will be activated. -Setting `quarkus.oidc.credentials.secret` will mostly likely be required for Keycloak and other providers for the authorization code flow initiated from Dev UI to complete, unless the client identified with `quarkus.oidc.client-id` is configured as a public client in your OpenId Connect provider's administration console. +Setting `quarkus.oidc.credentials.secret` will mostly likely be required for Keycloak and other providers for the authorization code flow initiated from Dev UI to complete, unless the client identified with `quarkus.oidc.client-id` is configured as a public client in your OpenID Connect provider's administration console. Run `mvn`quarkus:dev` and you will see the following message: [source,shell] @@ -234,9 +234,9 @@ $ mvn quarkus:dev ... ---- -If the provider metadata discovery has been successful then, after you open the main link:http://localhost:8080/q/dev[Dev UI page], you will see the `OpenId Connect Card` page linking to `Dev Console`: +If the provider metadata discovery has been successful then, after you open the main link:http://localhost:8080/q/dev[Dev UI page], you will see the `OpenID Connect Card` page linking to `Dev Console`: -image::dev-ui-oidc-devconsole-card.png[alt=Generic Dev UI OpenId Connect Card,role="center"] +image::dev-ui-oidc-devconsole-card.png[alt=Generic Dev UI OpenID Connect Card,role="center"] Follow the link and you'll be able log in to your provider, get the tokens and test the application. The experience will be the same as described in the <> section, where `Dev Services for Keycloak` container has been started, especially if you work with Keycloak (please also pay attention to a `redirect_uri` note in that section). @@ -247,7 +247,7 @@ If you work with other providers then a Dev UI experience described in the <> for more information. -Note that some OpenId Connect providers do not support https://openid.net/specs/openid-connect-session-1_0.html#RPLogout[RP-Initiated Logout] specification (possibly because it is still technically a draft) and do not return an OpenId Connect well-known `end_session_endpoint` metadata property. However it should not be a problem since these providers' specific logout mechanisms may only differ in how the logout URL query parameters are named. +Note that some OpenID Connect providers do not support https://openid.net/specs/openid-connect-session-1_0.html#RPLogout[RP-Initiated Logout] specification (possibly because it is still technically a draft) and do not return an OpenID Connect well-known `end_session_endpoint` metadata property. However it should not be a problem since these providers' specific logout mechanisms may only differ in how the logout URL query parameters are named. According to the https://openid.net/specs/openid-connect-session-1_0.html#RPLogout[RP-Initiated Logout] specification, the `quarkus.oidc.logout.post-logout-path` property is represented as a `post_logout_redirect_uri` query parameter which will not be recognized by the providers which do not support this specification. @@ -505,7 +505,7 @@ public class ServiceResource { [[session-management]] === Session Management -If you have a xref:security-openid-connect.adoc#single-page-applications[Single Page Application for Service Applications] where your OpenId Connect Provider script such as `keycloak.js` is managing an authoriization code flow then that script will also control the SPA authentication session lifespan. +If you have a xref:security-openid-connect.adoc#single-page-applications[Single Page Application for Service Applications] where your OpenID Connect Provider script such as `keycloak.js` is managing an authoriization code flow then that script will also control the SPA authentication session lifespan. If you work with a Quarkus OIDC `web-app` application then it is Quarkus OIDC Code Authentication mechanism which is managing the user session lifespan. @@ -646,14 +646,14 @@ If you plan to consume this application from a Single Page Application running o === Integration with GitHub and other OAuth2 providers -Some well known providers such as `GitHub` or `LinkedIn` are not `OpenId Connect` but `OAuth2` providers which support the `authorization code flow`, for example, link:https://docs.github.com/en/developers/apps/building-oauth-apps/authorizing-oauth-apps[GitHub OAuth2] and link:https://docs.microsoft.com/en-us/linkedin/shared/authentication/authorization-code-flow[LinkedIn OAuth2]. +Some well known providers such as `GitHub` or `LinkedIn` are not `OpenID Connect` but `OAuth2` providers which support the `authorization code flow`, for example, link:https://docs.github.com/en/developers/apps/building-oauth-apps/authorizing-oauth-apps[GitHub OAuth2] and link:https://docs.microsoft.com/en-us/linkedin/shared/authentication/authorization-code-flow[LinkedIn OAuth2]. -The main difference between `OpenId Connect` and `OAuth2` providers is that `OpenId Connect` providers, by building on top of `OAuth2`, return an `ID Token` representing a user authentication, in addition to the standard authorization code flow `access` and `refresh` tokens returned by `OAuth2` providers. +The main difference between `OpenID Connect` and `OAuth2` providers is that `OpenID Connect` providers, by building on top of `OAuth2`, return an `ID Token` representing a user authentication, in addition to the standard authorization code flow `access` and `refresh` tokens returned by `OAuth2` providers. `OAuth2` providers such as `GitHub` do not return `IdToken`, the fact of the user authentication is implicit and is indirectly represented by the `access` token which represents an authenticated user authorizing the current Quarkus `web-app` application to access some data on behalf of the authenticated user. For example, when working with `GitHub`, the Quarkus endpoint can acquire an `access` token which will allow it to request a `GitHub` profile of the current user. -In fact this is exactly how a standard `OpenId Connect` `UserInfo` acqusition also works - by authenticating into your `OpenId Connect` provider you also give a permission to Quarkus application to acquire your <> on your behalf - and it also shows what is meant by `OpenId Connect` being built on top of `OAuth2`. +In fact this is exactly how a standard `OpenID Connect` `UserInfo` acqusition also works - by authenticating into your `OpenID Connect` provider you also give a permission to Quarkus application to acquire your <> on your behalf - and it also shows what is meant by `OpenID Connect` being built on top of `OAuth2`. In order to support the integration with such `OAuth2` servers, `quarkus-oidc` needs to be configured to allow the authorization code flow responses without `IdToken`: `quarkus.oidc.authentication.id-token-required=false`. @@ -727,7 +727,7 @@ public class TokenResource { } ---- -If you support more than one social provider with the help of xref:security-openid-connect-multitenancy.adoc[OpenId Connect Multi-Tenancy], for example, `Google` which is an OpenId Connect Provider returning `IdToken` and `GitHub` which is an `OAuth2` provider returning no `IdToken` and only allowing to access `UserInfo` then you can have your endpoint working with only the injected `SecurityIdentity` for both `Google` and `GitHub` flows. A simple augmentation of `SecurityIdentity` will be required where a principal created with the internally generated `IdToken` will be replaced with the `UserInfo` based principal when the GiHub flow is active: +If you support more than one social provider with the help of xref:security-openid-connect-multitenancy.adoc[OpenID Connect Multi-Tenancy], for example, `Google` which is an OpenID Connect Provider returning `IdToken` and `GitHub` which is an `OAuth2` provider returning no `IdToken` and only allowing to access `UserInfo` then you can have your endpoint working with only the injected `SecurityIdentity` for both `Google` and `GitHub` flows. A simple augmentation of `SecurityIdentity` will be required where a principal created with the internally generated `IdToken` will be replaced with the `UserInfo` based principal when the GiHub flow is active: [source,java] ---- @@ -840,7 +840,7 @@ quarkus.oidc.token.issuer=https://accounts.google.com === Provider Endpoint configuration -OIDC `web-app` application needs to know OpenId Connect provider's authorization, token, `JsonWebKey` (JWK) set and possibly `UserInfo`, introspection and end session (RP-initiated logout) endpoint addresses. +OIDC `web-app` application needs to know OpenID Connect provider's authorization, token, `JsonWebKey` (JWK) set and possibly `UserInfo`, introspection and end session (RP-initiated logout) endpoint addresses. By default they are discovered by adding a `/.well-known/openid-configuration` path to the configured `quarkus.oidc.auth-server-url`. @@ -870,7 +870,7 @@ Please see xref:security-openid-connect-client.adoc#token-propagation[Token Prop [[oidc-provider-client-authentication]] === Oidc Provider Client Authentication -`quarkus.oidc.runtime.OidcProviderClient` is used when a remote request to an OpenId Connect Provider has to be done. It has to authenticate to the OpenId Connect Provider when the authorization code has to be exchanged for the ID, access and refresh tokens, when the ID and access tokens have to be refreshed or introspected. +`quarkus.oidc.runtime.OidcProviderClient` is used when a remote request to an OpenID Connect Provider has to be done. It has to authenticate to the OpenID Connect Provider when the authorization code has to be exchanged for the ID, access and refresh tokens, when the ID and access tokens have to be refreshed or introspected. All the https://openid.net/specs/openid-connect-core-1_0.html#ClientAuthentication[OIDC Client Authentication] options are supported, for example: @@ -974,7 +974,7 @@ quarkus.oidc.auth-server-url=http://localhost:8180/auth/realms/quarkus/ quarkus.oidc.client-id=quarkus-app quarkus.oidc.credentials.jwt.key-file=privateKey.pem -# This is a token key identifier 'kid' header - set it if your OpenId Connect provider requires it. +# This is a token key identifier 'kid' header - set it if your OpenID Connect provider requires it. # Note if the key is represented in a JSON Web Key (JWK) format with a `kid` property then # using 'quarkus.oidc.credentials.jwt.token-key-id' is not necessary. quarkus.oidc.credentials.jwt.token-key-id=mykey @@ -995,7 +995,7 @@ quarkus.oidc.credentials.jwt.issuer=custom-issuer ==== Apple POST JWT -Apple OpenId Connect Provider uses a `client_secret_post` method where a secret is a JWT produced with a `private_key_jwt` authentication method but with Apple account specific issuer and subject claims. +Apple OpenID Connect Provider uses a `client_secret_post` method where a secret is a JWT produced with a `private_key_jwt` authentication method but with Apple account specific issuer and subject claims. `quarkus-oidc` supports a non-standard `client_secret_post_jwt` authentication method which can be configured as follows: @@ -1111,7 +1111,7 @@ public class CodeFlowAuthorizationTest { Additionally, `OidcWiremockTestResource` set token issuer and audience to `https://service.example.com` which can be customized with `quarkus.test.oidc.token.issuer` and `quarkus.test.oidc.token.audience` system properties. -`OidcWiremockTestResource` can be used to emulate all OpenId Connect providers. +`OidcWiremockTestResource` can be used to emulate all OpenID Connect providers. [[integration-testing-keycloak-devservices]] ==== Dev Services for Keycloak @@ -1233,7 +1233,7 @@ OIDC authentication mechanism can be affected if your Quarkus application is run In such cases configuring Quarkus to recognize the original headers forwarded by the proxy will be required, see xref:http-reference.adoc#reverse-proxy[Running behind a reverse proxy] Vert.x documentation section for more information. -For example, if your Quarkus endpoint runs in a cluster behind Kubernetes Ingress then a redirect from the OpenId Connect Provider back to this endpoint may not work since the calculated `redirect_uri` parameter may point to the internal endpoint address. This problem can be resolved with the following configuration: +For example, if your Quarkus endpoint runs in a cluster behind Kubernetes Ingress then a redirect from the OpenID Connect Provider back to this endpoint may not work since the calculated `redirect_uri` parameter may point to the internal endpoint address. This problem can be resolved with the following configuration: [source,properties] ---- @@ -1247,9 +1247,9 @@ where `X-ORIGINAL-HOST` is set by Kubernetes Ingress to represent the external e `quarkus.oidc.authentication.force-redirect-https-scheme` property may also be used when the Quarkus application is running behind a SSL terminating reverse proxy. -=== External and Internal Access to OpenId Connect Provider +=== External and Internal Access to OpenID Connect Provider -Note that the OpenId Connect Provider externally accessible authorization, logout and other endpoints may have different HTTP(S) URLs compared to the URLs auto-discovered or configured relative to `quarkus.oidc.auth-server-url` internal URL. +Note that the OpenID Connect Provider externally accessible authorization, logout and other endpoints may have different HTTP(S) URLs compared to the URLs auto-discovered or configured relative to `quarkus.oidc.auth-server-url` internal URL. In such cases an issuer verification failure may be reported by the endpoint and redirects to the externally accessible Connect Provider endpoints may fail. In such cases, if you work with Keycloak then please start it with a `KEYCLOAK_FRONTEND_URL` system property set to the externally accessible base URL. @@ -1257,9 +1257,9 @@ If you work with other Openid Connect providers then please check your provider' === Customize authentication requests -By default, only the `response_type` (set to `code`), `scope` (set to 'openid'), `client_id`, `redirect_uri` and `state` properties are passed as HTTP query parameters to the OpenId Connect provider's authorization endpoint when the user is redirected to it to authenticate. +By default, only the `response_type` (set to `code`), `scope` (set to 'openid'), `client_id`, `redirect_uri` and `state` properties are passed as HTTP query parameters to the OpenID Connect provider's authorization endpoint when the user is redirected to it to authenticate. -You can add more properties to it with `quarkus.oidc.authentication.extra-params`. For example, some OpenId Connect providers may choose to return the authorization code as part of the redirect URI's fragment which would break the authentication process - it can be fixed as follows: +You can add more properties to it with `quarkus.oidc.authentication.extra-params`. For example, some OpenID Connect providers may choose to return the authorization code as part of the redirect URI's fragment which would break the authentication process - it can be fixed as follows: [source,properties] ---- diff --git a/docs/src/main/asciidoc/security-openid-connect.adoc b/docs/src/main/asciidoc/security-openid-connect.adoc index bc34942fdc7c5..ef3c9428278c5 100644 --- a/docs/src/main/asciidoc/security-openid-connect.adoc +++ b/docs/src/main/asciidoc/security-openid-connect.adoc @@ -8,11 +8,11 @@ https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc include::./attributes.adoc[] :toc: -This guide demonstrates how to use Quarkus OpenID Connect (OIDC) Extension to protect your JAX-RS applications using Bearer Token Authorization where Bearer Tokens are issued by OpenId Connect and OAuth 2.0 compliant Authorization Servers such as https://www.keycloak.org/about.html[Keycloak]. +This guide demonstrates how to use Quarkus OpenID Connect (OIDC) Extension to protect your JAX-RS applications using Bearer Token Authorization where Bearer Tokens are issued by OpenID Connect and OAuth 2.0 compliant Authorization Servers such as https://www.keycloak.org/about.html[Keycloak]. Bearer Token Authorization is the process of authorizing HTTP requests based on the existence and validity of a Bearer Token which provides valuable information to determine the subject of the call as well as whether or not an HTTP resource can be accessed. -Please read the xref:security-openid-connect-web-authentication.adoc[Using OpenID Connect to Protect Web Applications] guide if you need to authenticate and authorize the users using OpenId Connect Authorization Code Flow. +Please read the xref:security-openid-connect-web-authentication.adoc[Using OpenID Connect to Protect Web Applications] guide if you need to authenticate and authorize the users using OpenID Connect Authorization Code Flow. If you use Keycloak and Bearer tokens then also see the xref:security-keycloak-authorization.adoc[Using Keycloak to Centralize Authorization] guide. @@ -208,9 +208,9 @@ NOTE: If you want to use the Keycloak Admin Client to configure your server from To run the application in a dev mode, use `./mvnw clean compile quarkus:dev`. xref:security-openid-connect-dev-services.adoc[Dev Services for Keycloak] will launch a Keycloak container and import a `quarkus-realm.json`. -Open a xref:dev-ui.adoc[Dev UI] available at http://localhost:8080/q/dev[/q/dev] and click on a `Provider: Keycloak` link in an `OpenId Connect` `Dev UI` card. +Open a xref:dev-ui.adoc[Dev UI] available at http://localhost:8080/q/dev[/q/dev] and click on a `Provider: Keycloak` link in an `OpenID Connect` `Dev UI` card. -You will be asked to login into a `Single Page Application` provided by `OpenId Connect Dev UI`: +You will be asked to login into a `Single Page Application` provided by `OpenID Connect Dev UI`: * Login as `alice` (password: `alice`) who has a `user` role ** accessing `/api/admin` will return `403` @@ -356,13 +356,13 @@ Injection of `JsonWebToken` is supported in `@ApplicationScoped`, `@Singleton` a === User Info Set `quarkus.oidc.authentication.user-info-required=true` if a UserInfo JSON object from the OIDC userinfo endpoint has to be requested. -A request will be sent to the OpenId Provider UserInfo endpoint and an `io.quarkus.oidc.UserInfo` (a simple `javax.json.JsonObject` wrapper) object will be created. +A request will be sent to the OpenID Provider UserInfo endpoint and an `io.quarkus.oidc.UserInfo` (a simple `javax.json.JsonObject` wrapper) object will be created. `io.quarkus.oidc.UserInfo` can be either injected or accessed as a SecurityIdentity `userinfo` attribute. [[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 either injected or accessed as a `SecurityIdentity` `configuration-metadata` attribute. +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 either injected or accessed as a `SecurityIdentity` `configuration-metadata` attribute. The default tenant's `OidcConfigurationMetadata` is injected if the endpoint is public. @@ -385,11 +385,11 @@ Additionally a custom `SecurityIdentityAugmentor` can also be used to add the ro [[token-verification-introspection]] === Token Verification And Introspection -If the token is a JWT token then, by default, it will be verified with a `JsonWebKey` (JWK) key from a local `JsonWebKeySet` retrieved from the OpenId Connect Provider's JWK endpoint. The token's key identifier `kid` header value will be used to find the matching JWK key. +If the token is a JWT token then, by default, it will be verified with a `JsonWebKey` (JWK) key from a local `JsonWebKeySet` retrieved from the OpenID Connect Provider's JWK endpoint. The token's key identifier `kid` header value will be used to find the matching JWK key. If no matching `JWK` is available locally then `JsonWebKeySet` will be refreshed by fetching the current key set from the JWK endpoint. The `JsonWebKeySet` refresh can be repeated again only after the `quarkus.oidc.token.forced-jwk-refresh-interval` (default is 10 minutes) expires. -If no matching `JWK` is available after the refresh then the JWT token will be sent to the OpenId Connect Provider's token introspection endpoint. +If no matching `JWK` is available after the refresh then the JWT token will be sent to the OpenID Connect Provider's token introspection endpoint. -If the token is opaque (it can be a binary token or an encrypted JWT token) then it will always be sent to the OpenId Connect Provider's token introspection endpoint. +If the token is opaque (it can be a binary token or an encrypted JWT token) then it will always be sent to the OpenID Connect Provider's token introspection endpoint. If you work with JWT tokens only and expect that a matching `JsonWebKey` will always be available (possibly after a key set refresh) then you should disable the token introspection: @@ -414,7 +414,7 @@ Note that `io.quarkus.oidc.TokenIntrospection` (a simple `javax.json.JsonObject` [[token-introspection-userinfo-cache]] === Token Introspection and UserInfo Cache -All opaque and sometimes JWT Bearer access tokens have to be remotely introspected. If `UserInfo` is also required then the same access token will be used to do a remote call to OpenId Connect Provider again. So, if `UserInfo` is required and the current access token is opaque then for every such token there will be 2 remote calls done - one to introspect it and one to get UserInfo with it, and if the token is JWT then usually only a single remote call will be needed - to get UserInfo with it. +All opaque and sometimes JWT Bearer access tokens have to be remotely introspected. If `UserInfo` is also required then the same access token will be used to do a remote call to OpenID Connect Provider again. So, if `UserInfo` is required and the current access token is opaque then for every such token there will be 2 remote calls done - one to introspect it and one to get UserInfo with it, and if the token is JWT then usually only a single remote call will be needed - to get UserInfo with it. The cost of making up to 2 remote calls per every incoming bearer or code flow access token can sometimes be problematic. @@ -499,7 +499,7 @@ Note it is also recommended to use `quarkus.oidc.token.audience` property to ver [[single-page-applications]] === Single Page Applications -Single Page Application (SPA) typically uses `XMLHttpRequest`(XHR) and the Java Script utility code provided by the OpenId Connect provider to acquire a bearer token and use it +Single Page Application (SPA) typically uses `XMLHttpRequest`(XHR) and the Java Script utility code provided by the OpenID Connect provider to acquire a bearer token and use it to access Quarkus `service` applications. For example, here is how you can use `keycloak.js` to authenticate the users and refresh the expired tokens from the SPA: @@ -546,11 +546,11 @@ For example, here is how you can use `keycloak.js` to authenticate the users and === Cross Origin Resource Sharing -If you plan to consume your OpenId Connect `service` application from a Single Page Application running on a different domain, you will need to configure CORS (Cross-Origin Resource Sharing). Please read the xref:http-reference.adoc#cors-filter[HTTP CORS documentation] for more details. +If you plan to consume your OpenID Connect `service` application from a Single Page Application running on a different domain, you will need to configure CORS (Cross-Origin Resource Sharing). Please read the xref:http-reference.adoc#cors-filter[HTTP CORS documentation] for more details. === Provider Endpoint configuration -OIDC `service` application needs to know OpenId Connect provider's token, `JsonWebKey` (JWK) set and possibly `UserInfo` and introspection endpoint addresses. +OIDC `service` application needs to know OpenID Connect provider's token, `JsonWebKey` (JWK) set and possibly `UserInfo` and introspection endpoint addresses. By default they are discovered by adding a `/.well-known/openid-configuration` path to the configured `quarkus.oidc.auth-server-url`. @@ -577,7 +577,7 @@ Please see xref:security-openid-connect-client.adoc#token-propagation[Token Prop [[oidc-provider-authentication]] === Oidc Provider Client Authentication -`quarkus.oidc.runtime.OidcProviderClient` is used when a remote request to an OpenId Connect Provider has to be done. If the bearer token has to be introspected then `OidcProviderClient` has to authenticate to the OpenId Connect Provider. Please see xref:security-openid-connect-web-authentication.adoc#oidc-provider-client-authentication[OidcProviderClient Authentication] for more information about all the supported authentication options. +`quarkus.oidc.runtime.OidcProviderClient` is used when a remote request to an OpenID Connect Provider has to be done. If the bearer token has to be introspected then `OidcProviderClient` has to authenticate to the OpenID Connect Provider. Please see xref:security-openid-connect-web-authentication.adoc#oidc-provider-client-authentication[OidcProviderClient Authentication] for more information about all the supported authentication options. [[integration-testing]] === Testing @@ -1080,23 +1080,23 @@ quarkus.log.category."io.quarkus.oidc.runtime.OidcRecorder".level=TRACE quarkus.log.category."io.quarkus.oidc.runtime.OidcRecorder".min-level=TRACE ---- -=== External and Internal Access to OpenId Connect Provider +=== External and Internal Access to OpenID Connect Provider -Note that the OpenId Connect Provider externally accessible token and other endpoints may have different HTTP(S) URLs compared to the URLs auto-discovered or configured relative to `quarkus.oidc.auth-server-url` internal URL. For example, if your SPA acquires a token from an external token endpoint address and sends it to Quarkus as a Bearer token then an issuer verification failure may be reported by the endpoint. +Note that the OpenID Connect Provider externally accessible token and other endpoints may have different HTTP(S) URLs compared to the URLs auto-discovered or configured relative to `quarkus.oidc.auth-server-url` internal URL. For example, if your SPA acquires a token from an external token endpoint address and sends it to Quarkus as a Bearer token then an issuer verification failure may be reported by the endpoint. In such cases, if you work with Keycloak then please start it with a `KEYCLOAK_FRONTEND_URL` system property set to the externally accessible base URL. If you work with other Openid Connect providers then please check your provider's documentation. === How to use 'client-id' property -`quarkus.oidc.client-id` property identifies an OpenId Connect Client which requested the current bearer token. It can be an SPA application running in a browser or a Quarkus `web-app` confidential client application propagating the access token to the Quarkus `service` application. +`quarkus.oidc.client-id` property identifies an OpenID Connect Client which requested the current bearer token. It can be an SPA application running in a browser or a Quarkus `web-app` confidential client application propagating the access token to the Quarkus `service` application. This property is required if the `service` application is expected to introspect the tokens remotely - which is always the case for the opaque tokens. This property is optional if the local Json Web Key token verification only is used. Nonetheless, setting this property is encouraged even if the endpoint does not require an access to the remote introspection endpoint. The reasons behind it that `client-id`, if set, can be used to verify the token audience and will also be included in the logs when the token verification fails for the better traceability of the tokens issued to specific clients to be analyzed over a longer period of time. -For example, if your OpenId Connect provider sets a token audience then the following configuration pattern is recommended: +For example, if your OpenID Connect provider sets a token audience then the following configuration pattern is recommended: [source, properties] ---- @@ -1106,7 +1106,7 @@ quarkus.oidc.client-id=quarkus-app quarkus.oidc.token.audience=${quarkus.oidc.client-id} ---- -If you set `quarkus.oidc.client-id` but your endpoint does not require a remote access to one of OpenId Connect Provider endpoints (introspection, token acquisition, etc) then do not set a client secret with the `quarkus.oidc.credentials` or similar properties as it will not be used. +If you set `quarkus.oidc.client-id` but your endpoint does not require a remote access to one of OpenID Connect Provider endpoints (introspection, token acquisition, etc) then do not set a client secret with the `quarkus.oidc.credentials` or similar properties as it will not be used. Note Quarkus `web-app` applications always require `quarkus.oidc.client-id` property. diff --git a/docs/src/main/asciidoc/security-testing.adoc b/docs/src/main/asciidoc/security-testing.adoc index 5a5113d9ad0e0..bb0c64ad94dbd 100644 --- a/docs/src/main/asciidoc/security-testing.adoc +++ b/docs/src/main/asciidoc/security-testing.adoc @@ -82,7 +82,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-openid-connect.adoc#integration-testing-security-annotation[OpenId Connect Bearer Token Integration testing], xref:security-openid-connect-web-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-openid-connect.adoc#integration-testing-security-annotation[OpenID Connect Bearer Token Integration testing], xref:security-openid-connect-web-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`. [WARNING] ==== @@ -98,7 +98,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#integration-testing.adoc[OAuth2 Integration testing], xref:security-openid-connect.adoc#integration-testing-wiremock[OpenId Connect Bearer Token Integration testing], xref:security-openid-connect-web-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#integration-testing.adoc[OAuth2 Integration testing], xref:security-openid-connect.adoc#integration-testing-wiremock[OpenID Connect Bearer Token Integration testing], xref:security-openid-connect-web-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. == References diff --git a/docs/src/main/asciidoc/security.adoc b/docs/src/main/asciidoc/security.adoc index ac90cef9007ca..ad7ef8e2528c4 100644 --- a/docs/src/main/asciidoc/security.adoc +++ b/docs/src/main/asciidoc/security.adoc @@ -42,12 +42,12 @@ Quarkus provides Mutual TLS authentication so that you can authenticate users ba Please see xref:security-built-in-authentication.adoc#mutual-tls[Mutual TLS Authentication] for more information. -=== OpenId Connect +=== OpenID Connect -`quarkus-oidc` extension provides a reactive, interoperable, multi-tenant enabled OpenId Connect adapter which supports `Bearer Token` and `Authorization Code Flow` authentication mechanisms. +`quarkus-oidc` extension provides a reactive, interoperable, multi-tenant enabled OpenID Connect adapter which supports `Bearer Token` and `Authorization Code Flow` authentication mechanisms. `Bearer Token` mechanism extracts the token from HTTP `Authorization` header. -`Authorization Code Flow` mechanism uses OpenId Connect Authorization Code flow. It redirects the user to IDP to authenticate and completes the authentication process after the user has been redirected back to Quarkus by exchanging the provided code grant for ID, access and refresh tokens. +`Authorization Code Flow` mechanism uses OpenID Connect Authorization Code flow. It redirects the user to IDP to authenticate and completes the authentication process after the user has been redirected back to Quarkus by exchanging the provided code grant for ID, access and refresh tokens. ID and access `JWT` tokens are verified with the refreshable `JWK` key set but both JWT and opaque (binary) tokens can be introspected remotely. @@ -75,13 +75,13 @@ If you use Keycloak and Bearer tokens then also see the xref:security-keycloak-a If you need to configure Keycloak programmatically then consider using https://www.keycloak.org/docs/latest/server_development/#admin-rest-api[Keycloak Admin REST API] with the help of the `quarkus-keycloak-admin-client` extension. ==== -=== OpenId Connect Client and Filters +=== OpenID Connect Client and Filters -`quarkus-oidc-client` extension provides `OidcClient` for acquiring and refreshing access tokens from OpenId Connect and OAuth2 providers which support `client-credentials`, `password` and `refresh_token` token grants. +`quarkus-oidc-client` extension provides `OidcClient` for acquiring and refreshing access tokens from OpenID Connect and OAuth2 providers which support `client-credentials`, `password` and `refresh_token` token grants. -`quarkus-oidc-client-filter` extension depends on the `quarkus-oidc-client` extension and provides JAX-RS `OidcClientRequestFilter` which sets the access token acquired by `OidcClient` as an HTTP `Authorization` header's `Bearer` scheme value. This filter can be registered with MP RestClient implementations injected into the current Quarkus endpoint but it is not related to the authentication requirements of this service endpoint. For example, it can be a public endpoint or it can be protected with MTLS - the important point is that this Quarkus endpoint does not have to be protected itself with the Quarkus OpenId Connect adapter. +`quarkus-oidc-client-filter` extension depends on the `quarkus-oidc-client` extension and provides JAX-RS `OidcClientRequestFilter` which sets the access token acquired by `OidcClient` as an HTTP `Authorization` header's `Bearer` scheme value. This filter can be registered with MP RestClient implementations injected into the current Quarkus endpoint but it is not related to the authentication requirements of this service endpoint. For example, it can be a public endpoint or it can be protected with MTLS - the important point is that this Quarkus endpoint does not have to be protected itself with the Quarkus OpenID Connect adapter. -`quarkus-oidc-token-propagation` extension depends on the `quarkus-oidc` extension and provides JAX-RS `TokenCredentialRequestFilter` which sets the OpenId Connect Bearer or Authorization Code Flow access token as an HTTP `Authorization` header's `Bearer` scheme value. This filter can be registered with MP RestClient implementations injected into the current Quarkus endpoint and the Quarkus endpoint must be protected itself with the Quarkus OpenId Connect adapter. This filter can be used to propagate the access token to the downstream services. +`quarkus-oidc-token-propagation` extension depends on the `quarkus-oidc` extension and provides JAX-RS `TokenCredentialRequestFilter` which sets the OpenID Connect Bearer or Authorization Code Flow access token as an HTTP `Authorization` header's `Bearer` scheme value. This filter can be registered with MP RestClient implementations injected into the current Quarkus endpoint and the Quarkus endpoint must be protected itself with the Quarkus OpenID Connect adapter. This filter can be used to propagate the access token to the downstream services. See the xref:security-openid-connect-client.adoc[Using OpenID Connect and OAuth2 Client] guide for more information. @@ -103,17 +103,17 @@ See the xref:security-jwt.adoc[Using SmallRye JWT] guide for more information. See the xref:security-oauth2.adoc[Using OAuth2] guide for more information. [[oidc-jwt-oauth2-comparison]] -=== Choosing between OpenId Connect, SmallRye JWT and OAuth2 extensions +=== Choosing between OpenID Connect, SmallRye JWT and OAuth2 extensions -`quarkus-oidc` extension requires an OpenId Connect provider such as Keycloak which can be used to verify the Bearer tokens or authenticate the end users with the Authorization Code flow. In both cases `quarkus-oidc` requires a connection to this OpenId Connect provider. +`quarkus-oidc` extension requires an OpenID Connect provider such as Keycloak which can be used to verify the Bearer tokens or authenticate the end users with the Authorization Code flow. In both cases `quarkus-oidc` requires a connection to this OpenID Connect provider. `quarkus-oidc` is the only option when the user authentication via Authorization Code flow or supporting multiple tenants is required. It can also request a UserInfo using both Authorization Code Flow and Bearer access tokens. When the Bearer tokens have to be verified then `quarkus-oidc`, `quarkus-smallrye-jwt` and `quarkus-elytron-security-oauth2` can be used. -If you have Bearer tokens in a JWT format then all these 3 extensions can be used. Both `quarkus-oidc` and `quarkus-smallrye-jwt` support refreshing the JsonWebKey (JWK) set when the OpenId Connect provider rotates the keys, therefore `quarkus-oidc` or `quarkus-smallrye-jwt` should be used for verifying JWT tokens if the remote token introspection has to be avoided or not supported by the providers. +If you have Bearer tokens in a JWT format then all these 3 extensions can be used. Both `quarkus-oidc` and `quarkus-smallrye-jwt` support refreshing the JsonWebKey (JWK) set when the OpenID Connect provider rotates the keys, therefore `quarkus-oidc` or `quarkus-smallrye-jwt` should be used for verifying JWT tokens if the remote token introspection has to be avoided or not supported by the providers. -`quarkus-smallrye-jwt` does not support the remote introspection of the opaque tokens or even JWT tokens - it always relies on the locally available keys - possibly fetched from the OpenId Connect provider. So if you need to introspect the JWT tokens remotely then both `quarkus-oidc` and `quarkus-elytron-security-oauth2` will work. Both extensions also support the verification of the opaque/binary tokens via the remote introspection. +`quarkus-smallrye-jwt` does not support the remote introspection of the opaque tokens or even JWT tokens - it always relies on the locally available keys - possibly fetched from the OpenID Connect provider. So if you need to introspect the JWT tokens remotely then both `quarkus-oidc` and `quarkus-elytron-security-oauth2` will work. Both extensions also support the verification of the opaque/binary tokens via the remote introspection. `quarkus-oidc` and `quarkus-smallrye-jwt` can have both JWT and opaque tokens injected into the endpoint code - the injected JWT tokens may offer a richer information about the user. All extensions can have the tokens injected as `Principal`.