Skip to content

Commit

Permalink
Edit the OIDC and OAuth2 Client and Filters Reference Guide
Browse files Browse the repository at this point in the history
  • Loading branch information
rolfedh committed Dec 5, 2023
1 parent 6e146aa commit 1487183
Showing 1 changed file with 23 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ 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
////
= OpenID Connect (OIDC) and OAuth2 Client and Filters Reference Guide
= OpenID Connect (OIDC) and OAuth2 client and filters reference guide

Check warning on line 6 in docs/src/main/asciidoc/security-openid-connect-client-reference.adoc

View workflow job for this annotation

GitHub Actions / Linting with Vale

[vale] reported by reviewdog 🐶 [Quarkus.Headings] Use sentence-style capitalization in 'OpenID Connect (OIDC) and OAuth2 client and filters reference guide'. Raw Output: {"message": "[Quarkus.Headings] Use sentence-style capitalization in 'OpenID Connect (OIDC) and OAuth2 client and filters reference guide'.", "location": {"path": "docs/src/main/asciidoc/security-openid-connect-client-reference.adoc", "range": {"start": {"line": 6, "column": 3}}}, "severity": "INFO"}
include::_attributes.adoc[]
:categories: security
:topics: security,oidc,client
Expand All @@ -30,11 +30,11 @@ Add the following dependency:
</dependency>
----

`quarkus-oidc-client` extension provides a reactive `io.quarkus.oidc.client.OidcClient` which can be used to acquire and refresh tokens using SmallRye Mutiny `Uni` and `Vert.x WebClient`.
The `quarkus-oidc-client` extension provides a reactive `io.quarkus.oidc.client.OidcClient`, which can be used to acquire and refresh tokens using SmallRye Mutiny `Uni` and `Vert.x WebClient`.

Check warning on line 33 in docs/src/main/asciidoc/security-openid-connect-client-reference.adoc

View workflow job for this annotation

GitHub Actions / Linting with Vale

[vale] reported by reviewdog 🐶 [Quarkus.TermsSuggestions] Depending on the context, consider using 'by using' or 'that uses' rather than 'using'. Raw Output: {"message": "[Quarkus.TermsSuggestions] Depending on the context, consider using 'by using' or 'that uses' rather than 'using'.", "location": {"path": "docs/src/main/asciidoc/security-openid-connect-client-reference.adoc", "range": {"start": {"line": 33, "column": 141}}}, "severity": "INFO"}

`OidcClient` is initialized at the build time with the IDP token endpoint URL, which can be auto-discovered or manually configured, and uses this endpoint to acquire access tokens using the token grants such as `client_credentials` or `password` and refresh the tokens using a `refresh_token` grant.
`OidcClient` is initialized at the build time with the IDP token endpoint URL, which can be auto-discovered or manually configured. `OidcClient` uses this endpoint to acquire access tokens by using token grants such as `client_credentials` or `password` and refresh the tokens by using a `refresh_token` grant.

Check warning on line 35 in docs/src/main/asciidoc/security-openid-connect-client-reference.adoc

View workflow job for this annotation

GitHub Actions / Linting with Vale

[vale] reported by reviewdog 🐶 [Quarkus.SentenceLength] Try to keep sentences to an average of 32 words or fewer. Raw Output: {"message": "[Quarkus.SentenceLength] Try to keep sentences to an average of 32 words or fewer.", "location": {"path": "docs/src/main/asciidoc/security-openid-connect-client-reference.adoc", "range": {"start": {"line": 35, "column": 14}}}, "severity": "INFO"}

=== Token Endpoint Configuration
=== Token endpoint configuration

By default, the token endpoint address is discovered by adding a `/.well-known/openid-configuration` path to the configured `quarkus.oidc-client.auth-server-url`.

Expand All @@ -47,7 +47,7 @@ quarkus.oidc-client.auth-server-url=http://localhost:8180/auth/realms/quarkus

`OidcClient` will discover that the token endpoint URL is `http://localhost:8180/auth/realms/quarkus/protocol/openid-connect/tokens`.

Alternatively, if the discovery endpoint is not available or you want to save on the discovery endpoint round-trip, you can disable the discovery and configure the token endpoint address with a relative path value; for example:
Alternatively, if the discovery endpoint is not available or you want to save on the discovery endpoint round-trip, you can disable the discovery and configure the token endpoint address with a relative path value. For example:

Check warning on line 50 in docs/src/main/asciidoc/security-openid-connect-client-reference.adoc

View workflow job for this annotation

GitHub Actions / Linting with Vale

[vale] reported by reviewdog 🐶 [Quarkus.SentenceLength] Try to keep sentences to an average of 32 words or fewer. Raw Output: {"message": "[Quarkus.SentenceLength] Try to keep sentences to an average of 32 words or fewer.", "location": {"path": "docs/src/main/asciidoc/security-openid-connect-client-reference.adoc", "range": {"start": {"line": 50, "column": 1}}}, "severity": "INFO"}

[source, properties]
----
Expand All @@ -66,11 +66,11 @@ quarkus.oidc-client.token-path=http://localhost:8180/auth/realms/quarkus/protoco

Setting `quarkus.oidc-client.auth-server-url` and `quarkus.oidc-client.discovery-enabled` is not required in this case.

=== Supported Token Grants
=== Supported token grants

The main token grants that `OidcClient` can use to acquire the tokens are the `client_credentials` (default) and `password` grants.

==== Client Credentials Grant
==== Client credentials grant

Here is how `OidcClient` can be configured to use the `client_credentials` grant:

Expand All @@ -93,7 +93,7 @@ quarkus.oidc-client.grant.type=client
quarkus.oidc-client.grant-options.client.audience=https://example.com/api
----

==== Password Grant
==== Password grant

Here is how `OidcClient` can be configured to use the `password` grant:

Expand All @@ -107,9 +107,9 @@ quarkus.oidc-client.grant-options.password.username=alice
quarkus.oidc-client.grant-options.password.password=alice
----

It can be further customized using a `quarkus.oidc-client.grant-options.password` configuration prefix, similar to how the client credentials grant can be customized.
It can be further customized by using a `quarkus.oidc-client.grant-options.password` configuration prefix, similar to how the client credentials grant can be customized.

==== Other Grants
==== Other grants

`OidcClient` can also help acquire the tokens by using grants that require some extra input parameters that cannot be captured in the configuration. These grants are `refresh_token` (with the external refresh token), `authorization_code`, as well as two grants which can be used to exchange the current access token, `urn:ietf:params:oauth:grant-type:token-exchange` and `urn:ietf:params:oauth:grant-type:jwt-bearer`.

Check warning on line 114 in docs/src/main/asciidoc/security-openid-connect-client-reference.adoc

View workflow job for this annotation

GitHub Actions / Linting with Vale

[vale] reported by reviewdog 🐶 [Quarkus.TermsSuggestions] Depending on the context, consider using 'because' or 'while' rather than 'as'. Raw Output: {"message": "[Quarkus.TermsSuggestions] Depending on the context, consider using 'because' or 'while' rather than 'as'.", "location": {"path": "docs/src/main/asciidoc/security-openid-connect-client-reference.adoc", "range": {"start": {"line": 114, "column": 240}}}, "severity": "INFO"}

Check warning on line 114 in docs/src/main/asciidoc/security-openid-connect-client-reference.adoc

View workflow job for this annotation

GitHub Actions / Linting with Vale

[vale] reported by reviewdog 🐶 [Quarkus.TermsSuggestions] Depending on the context, consider using ', which (non restrictive clause preceded by a comma)' or 'that (restrictive clause without a comma)' rather than 'which'. Raw Output: {"message": "[Quarkus.TermsSuggestions] Depending on the context, consider using ', which (non restrictive clause preceded by a comma)' or 'that (restrictive clause without a comma)' rather than 'which'.", "location": {"path": "docs/src/main/asciidoc/security-openid-connect-client-reference.adoc", "range": {"start": {"line": 114, "column": 261}}}, "severity": "INFO"}

Expand Down Expand Up @@ -196,7 +196,7 @@ public class OidcClientResource {
}
----

=== Inject Tokens
=== Inject tokens

You can inject `Tokens` that use `OidcClient` internally. `Tokens` can be used to acquire the access tokens and refresh them if necessary:

Expand Down Expand Up @@ -328,9 +328,9 @@ public class OidcClientResource {
----

[[named-oidc-clients]]
=== Inject named OidcClient and Tokens
=== Inject named OidcClient and tokens

In case of multiple configured ``OidcClient``s you can specify the `OidcClient` injection target by the extra qualifier `@NamedOidcClient` instead of working with `OidcClients`:
In case of multiple configured `OidcClient` objects, you can specify the `OidcClient` injection target by the extra qualifier `@NamedOidcClient` instead of working with `OidcClients`:

[source,java]
----
Expand Down Expand Up @@ -529,7 +529,7 @@ public interface ProtectedResourceService {
}
----

=== Use Custom RestClient ClientFilter
=== Use a custom RestClient ClientFilter

Check warning on line 532 in docs/src/main/asciidoc/security-openid-connect-client-reference.adoc

View workflow job for this annotation

GitHub Actions / Linting with Vale

[vale] reported by reviewdog 🐶 [Quarkus.Headings] Use sentence-style capitalization in 'Use a custom RestClient ClientFilter'. Raw Output: {"message": "[Quarkus.Headings] Use sentence-style capitalization in 'Use a custom RestClient ClientFilter'.", "location": {"path": "docs/src/main/asciidoc/security-openid-connect-client-reference.adoc", "range": {"start": {"line": 532, "column": 5}}}, "severity": "INFO"}

If you prefer, you can use your own custom filter and inject `Tokens`:

Expand All @@ -556,26 +556,26 @@ The `Tokens` producer will acquire and refresh the tokens, and the custom filter
You can also inject named `Tokens`, see <<named-oidc-clients,Inject named OidcClient and Tokens>>

[[refresh-access-tokens]]
=== Refreshing Access Tokens
=== Refreshing access tokens

`OidcClientRequestReactiveFilter`, `OidcClientRequestFilter` and `Tokens` producers will refresh the current expired access token if the refresh token is available.
Additionally, the `quarkus.oidc-client.refresh-token-time-skew` property can be used for a preemptive access token refreshment to avoid sending nearly expired access tokens that might cause HTTP 401 errors. For example, if this property is set to `3S` and the access token will expire in less than 3 seconds, then this token will be auto-refreshed.

If the access token needs to be refreshed, but no refresh token is available, then an attempt is made to acquire a new token using a configured grant, such as `client_credentials`.
If the access token needs to be refreshed, but no refresh token is available, then an attempt is made to acquire a new token by using a configured grant, such as `client_credentials`.

Check warning on line 564 in docs/src/main/asciidoc/security-openid-connect-client-reference.adoc

View workflow job for this annotation

GitHub Actions / Linting with Vale

[vale] reported by reviewdog 🐶 [Quarkus.Fluff] Depending on the context, consider using 'Rewrite the sentence, or use 'must', instead of' rather than 'needs to'. Raw Output: {"message": "[Quarkus.Fluff] Depending on the context, consider using 'Rewrite the sentence, or use 'must', instead of' rather than 'needs to'.", "location": {"path": "docs/src/main/asciidoc/security-openid-connect-client-reference.adoc", "range": {"start": {"line": 564, "column": 21}}}, "severity": "INFO"}

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 might also restrict the number of times a refresh token can be used.

[[revoke-access-tokens]]
=== Revoking Access Tokens
=== Revoking access tokens

If your OpenId Connect provider, such as Keycloak, supports a token revocation endpoint, then `OidcClient#revokeAccessToken` can be used to revoke the current access token. The revocation endpoint URL will be discovered alongside the token request URI or can be configured with `quarkus.oidc-client.revoke-path`.

You might want to have the access token revoked if using this token with a REST client fails with HTTP `401` or if the access token has already been used for a long time and you'd like to refresh it.

Check warning on line 573 in docs/src/main/asciidoc/security-openid-connect-client-reference.adoc

View workflow job for this annotation

GitHub Actions / Linting with Vale

[vale] reported by reviewdog 🐶 [Quarkus.SentenceLength] Try to keep sentences to an average of 32 words or fewer. Raw Output: {"message": "[Quarkus.SentenceLength] Try to keep sentences to an average of 32 words or fewer.", "location": {"path": "docs/src/main/asciidoc/security-openid-connect-client-reference.adoc", "range": {"start": {"line": 573, "column": 1}}}, "severity": "INFO"}

Check warning on line 573 in docs/src/main/asciidoc/security-openid-connect-client-reference.adoc

View workflow job for this annotation

GitHub Actions / Linting with Vale

[vale] reported by reviewdog 🐶 [Quarkus.TermsSuggestions] Depending on the context, consider using 'by using' or 'that uses' rather than 'using'. Raw Output: {"message": "[Quarkus.TermsSuggestions] Depending on the context, consider using 'by using' or 'that uses' rather than 'using'.", "location": {"path": "docs/src/main/asciidoc/security-openid-connect-client-reference.adoc", "range": {"start": {"line": 573, "column": 51}}}, "severity": "INFO"}

This can be achieved by requesting a token refresh using a refresh token. However, if the refresh token is unavailable, you can refresh it by revoking it first and then requesting a new access token.
This can be achieved by requesting a token refresh by using a refresh token. However, if the refresh token is unavailable, you can refresh it by revoking it first and then requesting a new access token.

[[oidc-client-authentication]]
=== OidcClient Authentication
=== OidcClient authentication

`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:
Expand Down Expand Up @@ -668,7 +668,7 @@ quarkus.oidc-client.credentials.jwt.key-id=mykeyAlias

Using `client_secret_jwt` or `private_key_jwt` authentication methods ensures that no client secret goes over the wire.

==== Additional JWT Authentication options
==== Additional JWT authentication options

If either `client_secret_jwt` or `private_key_jwt` authentication methods are used, then the JWT signature algorithm, key identifier, audience, subject, and issuer can be customized, for example:

Expand Down Expand Up @@ -912,7 +912,7 @@ public class OidcRequestCustomizer implements OidcRequestFilter {
[[token-propagation-reactive]]
== Token Propagation Reactive

The `quarkus-oidc-token-propagation-reactive` extension provides RestEasy Reactive Client `io.quarkus.oidc.token.propagation.reactive.AccessTokenRequestReactiveFilter` that simplifies the propagation of authentication information by propagating the xref:security-oidc-bearer-token-authentication.adoc[Bearer token] present in the current active request or the token acquired from the xref:security-oidc-code-flow-authentication.adoc[Authorization code flow mechanism], as the HTTP `Authorization` header's `Bearer` scheme value.
The `quarkus-oidc-token-propagation-reactive` extension provides a RestEasy Reactive Client, `io.quarkus.oidc.token.propagation.reactive.AccessTokenRequestReactiveFilter`, that simplifies the propagation of authentication information. This client propagates the xref:security-oidc-bearer-token-authentication.adoc[bearer token] present in the current active request or the token acquired from the xref:security-oidc-code-flow-authentication.adoc[authorization code flow mechanism] as the HTTP `Authorization` header's `Bearer` scheme value.

You can selectively register `AccessTokenRequestReactiveFilter` by using either `io.quarkus.oidc.token.propagation.AccessToken` or `org.eclipse.microprofile.rest.client.annotation.RegisterProvider` annotation, for example:

Expand Down Expand Up @@ -1039,7 +1039,7 @@ public interface ProtectedResourceService {

Alternatively, `AccessTokenRequestFilter` can be registered automatically with all MP Rest or Jakarta REST clients if the `quarkus.oidc-token-propagation.register-filter` property is set to `true` and `quarkus.oidc-token-propagation.json-web-token` property is set to `false` (which is a default value).

==== Exchange Token Before Propagation
==== 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:

Expand Down Expand Up @@ -1115,7 +1115,7 @@ public interface ProtectedResourceService {

Alternatively, `JsonWebTokenRequestFilter` can be registered automatically with all MicroProfile REST or Jakarta REST clients if both `quarkus.oidc-token-propagation.register-filter` and `quarkus.oidc-token-propagation.json-web-token` properties are set to `true`.

==== Update Token Before Propagation
==== Update token before propagation

If the injected token needs to have its `iss` (issuer) or `aud` (audience) claims updated and secured again with a new signature, then you can configure `JsonWebTokenRequestFilter` like this:

Expand Down

0 comments on commit 1487183

Please sign in to comment.