mirror of
https://github.com/keycloak/keycloak.git
synced 2026-01-09 23:12:06 -03:30
Documentation update for DPoP (#42865)
closes #42728 Signed-off-by: mposolda <mposolda@gmail.com> Signed-off-by: Marek Posolda <mposolda@gmail.com> Co-authored-by: andymunro <48995441+andymunro@users.noreply.github.com>
This commit is contained in:
parent
33c6e07c08
commit
e09ce9e18d
@ -30,6 +30,35 @@ The *Conditional - credential* is a new authenticator that checks if a specific
|
||||
|
||||
For more information about conditional flows, see link:{adminguide_link}#conditions-in-conditional-flows[Conditions in conditional flows].
|
||||
|
||||
= DPoP is now supported
|
||||
|
||||
{project_name} has support for OAuth 2.0 Demonstrating Proof-of-Possession at the Application Layer (DPoP), which was a preview feature since {project_name} 23. Also, the supported version includes some improvements and minor capabilities of the DPoP feature such as the following:
|
||||
|
||||
* Possibility to make just refresh tokens of a public client to be DPoP bound and omit the binding of an access tokens
|
||||
* All {project_name} endpoints that are secured by bearer token can now handle DPoP tokens. This includes for example admin REST API and account REST API
|
||||
* Possibility to require the `dpop_jkt` parameter in the OIDC authentication request
|
||||
|
||||
ifeval::[{project_community}==true]
|
||||
Thanks to
|
||||
https://github.com/tnorimat[Takashi Norimatsu] and https://github.com/dteleguin[Dmitry Telegin] for their contributions to the DPoP feature.
|
||||
endif::[]
|
||||
|
||||
For more information, see the link:{adminguide_link}#_dpop-bound-tokens[DPoP section] in the documentation.
|
||||
|
||||
= FAPI 2 Final support
|
||||
|
||||
{project_name} has support for the latest versions of FAPI 2 specifications. Specification *FAPI 2.0 security profile* is already promoted to Final and {project_name} supports it.
|
||||
Specification *FAPI 2.0 Message Signing* was not yet promoted at this time, but the latest draft is expected to be promoted to the Final version soon. {project_name} client policies support
|
||||
the final versions and corresponding client profiles for FAPI 2 are passing the FAPI conformance test suite.
|
||||
|
||||
Apart from some very minor polishing of existing policies, {project_name} has new client profiles (`fapi-2-dpop-security-profile` and `fapi-2-dpop-message-signing`) for the clients that use DPoP and are intended to be FAPI 2 compliant.
|
||||
|
||||
ifeval::[{project_community}==true]
|
||||
Thank you to https://github.com/tnorimat[Takashi Norimatsu] for contributing this.
|
||||
endif::[]
|
||||
|
||||
For more details, see the link:{securing_apps_base_link}/oidc-layers#_fapi-support[{securing_apps_name}].
|
||||
|
||||
= Option to force management interface to use HTTP
|
||||
|
||||
A new option, `http-management-scheme`, may be set to `http` to force the management interface to use HTTP rather than inheriting the HTTPS settings of the main interface.
|
||||
|
||||
@ -10,6 +10,8 @@ include::oidc/con-advanced-settings.adoc[leveloffset=+1]
|
||||
|
||||
include::oidc/con-confidential-client-credentials.adoc[leveloffset=+1]
|
||||
|
||||
include::oidc/con-dpop.adoc[leveloffset=+1]
|
||||
|
||||
include::oidc/con-secret-rotation.adoc[leveloffset=+1]
|
||||
|
||||
include::oidc/proc-secret-rotation.adoc[leveloffset=+1]
|
||||
|
||||
@ -97,42 +97,6 @@ See https://datatracker.ietf.org/doc/html/draft-ietf-oauth-mtls-08#section-3[Mut
|
||||
{project_name} client adapters do not support holder-of-key token verification. {project_name} adapters treat access and refresh tokens as bearer tokens.
|
||||
====
|
||||
|
||||
[[_dpop-bound-tokens]]
|
||||
*OAuth 2.0 Demonstrating Proof-of-Possession at the Application Layer (DPoP)*
|
||||
|
||||
DPoP binds an access token and a refresh token together with the public part of a client's key pair. This binding prevents an attacker from using stolen tokens.
|
||||
|
||||
This type of token is a holder-of-key token. Unlike bearer tokens, the recipient of a holder-of-key token can verify if the sender of the token is legitimate.
|
||||
|
||||
If the client switch `Require DPoP bound tokens` is on (*Settings tab*, section *Capability config*), the workflow is:
|
||||
|
||||
. A token request is sent to the token endpoint in an authorization code flow or hybrid flow.
|
||||
. {project_name} requests a DPoP proof.
|
||||
. {project_name} receives the DPoP proof.
|
||||
. {project_name} successfully verifies the DPoP proof.
|
||||
|
||||
If verification fails, {project_name} rejects the token.
|
||||
|
||||
If the switch `Require DPoP bound tokens` is off, the client can still send `DPoP` proof in the token request. In that case, {project_name} will verify DPoP proof
|
||||
and will add the thumbprint to the token. But if the switch is off, DPoP binding is not enforced by the {project_name} server for this client. It is recommended to have this switch
|
||||
on if you want to make sure that particular client always uses DPoP binding.
|
||||
|
||||
In the following cases, {project_name} will verify the client sending the access token or the refresh token:
|
||||
|
||||
* A token refresh request is sent to the token endpoint with a holder-of-key refresh token. This verification is done only for public clients as described in the DPoP specification. For confidential clients, the verification is not done as client authentication with proper client credentials is in place to ensure that request comes from the legitimate client. For public clients, both access tokens and refresh tokens are DPoP bound. For confidential clients, only access tokens are DPoP bound.
|
||||
* A UserInfo request is sent to UserInfo endpoint with a holder-of-key access token.
|
||||
* A logout request is sent to a non-OIDC compliant {project_name} proprietary logout endpoint Logout endpoint with a holder-of-key refresh token. This verification is done only for public clients as described above.
|
||||
|
||||
See https://datatracker.ietf.org/doc/html/rfc9449[OAuth 2.0 Demonstrating Proof of Possession (DPoP)] for more details.
|
||||
|
||||
[NOTE]
|
||||
====
|
||||
{project_name} client adapters do not support DPoP holder-of-key token verification. {project_name} adapters treat access and refresh tokens as bearer tokens.
|
||||
====
|
||||
|
||||
:tech_feature_name: DPoP
|
||||
:tech_feature_id: dpop
|
||||
include::../../templates/techpreview.adoc[]
|
||||
|
||||
[[_client_advanced_settings_oidc]]
|
||||
*Advanced Settings for OIDC*
|
||||
@ -161,19 +125,6 @@ image:images/client-advanced-settings-oidc.png[Advanced Settings]
|
||||
|
||||
|===
|
||||
|
||||
[[_proof-key-for-code-exchange]]
|
||||
*Proof Key for Code Exchange Code Challenge Method*
|
||||
|
||||
If an attacker steals an authorization code of a legitimate client, Proof Key for Code Exchange (PKCE) prevents the attacker from receiving the tokens that apply to the code.
|
||||
|
||||
An administrator can select one of these options:
|
||||
|
||||
*(blank)*:: {project_name} does not apply PKCE unless the client sends appropriate PKCE parameters to {project_name}s authorization endpoint.
|
||||
*S256*:: {project_name} applies to the client PKCE whose code challenge method is S256.
|
||||
*plain*:: {project_name} applies to the client PKCE whose code challenge method is plain.
|
||||
|
||||
See https://datatracker.ietf.org/doc/html/rfc7636[RFC 7636 Proof Key for Code Exchange by OAuth Public Clients] for more details.
|
||||
|
||||
[[_mapping-acr-to-loa-client]]
|
||||
*ACR to Level of Authentication (LoA) Mapping*
|
||||
|
||||
|
||||
@ -48,14 +48,16 @@ the legacy {project_name} Java OIDC adapters or by the link:https://docs.wildfly
|
||||
== Capability Config
|
||||
[[_access-type]]
|
||||
|
||||
*Client authentication*:: The type of OIDC client.
|
||||
*Client authentication*:: Specifies the type of OIDC client.
|
||||
* _ON_
|
||||
+
|
||||
For server-side clients that perform browser logins and require client secrets when making an Access Token Request. This setting should be used for server-side applications.
|
||||
Clients with the client authentication enabled are referred as confidential clients. For more details, see <<_client-credentials, Client credentials>>.
|
||||
|
||||
* _OFF_
|
||||
+
|
||||
For client-side clients that perform browser logins. As it is not possible to ensure that secrets can be kept safe with client-side clients, it is important to restrict access by configuring correct redirect URIs.
|
||||
Clients with the client authentication enabled are referred as public clients.
|
||||
|
||||
*Authorization*:: Enables or disables fine-grained authorization support for this client.
|
||||
|
||||
@ -73,6 +75,24 @@ For client-side clients that perform browser logins. As it is not possible to en
|
||||
|
||||
*OIDC CIBA Grant*:: If enabled, this client can use the OIDC xref:con-oidc-auth-flows_{context}[Client Initiated Backchannel Authentication Grant].
|
||||
|
||||
[[_proof-key-for-code-exchange]]
|
||||
*PKCE method*
|
||||
|
||||
If an attacker steals an authorization code of a legitimate client, Proof Key for Code Exchange (PKCE) prevents the attacker from receiving the tokens that apply to the code. With this option,
|
||||
you can specify which PKCE challenge method is required for this client.
|
||||
|
||||
An administrator can select one of these options:
|
||||
|
||||
*(blank)*:: {project_name} does not apply PKCE unless the client sends the appropriate PKCE parameters to {project_name} authorization endpoint. So PKCE is still possible to use, but it is not required.
|
||||
*S256*:: {project_name} applies to the client PKCE whose code challenge method is S256.
|
||||
*plain*:: {project_name} applies to the client PKCE whose code challenge method is plain.
|
||||
|
||||
See https://datatracker.ietf.org/doc/html/rfc7636[RFC 7636 Proof Key for Code Exchange by OAuth Public Clients] for more details.
|
||||
|
||||
*Require DPoP bound tokens*
|
||||
|
||||
DPoP binds an access token and a refresh token together with the public part of a client's key pair. For the details, see <<_dpop-bound-tokens, DPoP>>.
|
||||
|
||||
== Login settings
|
||||
|
||||
*Login theme*:: A theme to use for login, OTP, grant registration, and forgotten password pages.
|
||||
|
||||
@ -0,0 +1,49 @@
|
||||
[id="con-dpop_{context}"]
|
||||
[[_dpop-bound-tokens]]
|
||||
= DPoP
|
||||
[role="_abstract"]
|
||||
|
||||
DPoP binds an access token and a refresh token together with the public part of a client's key pair. This binding prevents an attacker from using stolen tokens.
|
||||
|
||||
This type of token is a holder-of-key token. Unlike bearer tokens, the recipient of a holder-of-key token can verify if the sender of the token is legitimate.
|
||||
|
||||
If you enable *Require DPoP bound tokens* in the Admin Console *Settings* tab under *Capability config*, the workflow is:
|
||||
|
||||
. A token request is sent to the token endpoint in an authorization code flow or hybrid flow.
|
||||
. {project_name} requests a DPoP proof.
|
||||
. {project_name} receives the DPoP proof.
|
||||
. {project_name} successfully verifies the DPoP proof.
|
||||
|
||||
If verification fails, {project_name} rejects the token.
|
||||
|
||||
If *Require DPoP bound tokens* is off, the client can still send `DPoP` proof in the token request. In that case, {project_name} verifies DPoP proof
|
||||
and will add the thumbprint to the token. Also, if the switch is off, DPoP binding is not enforced by the {project_name} server for this client. It is recommended to have this switch
|
||||
on if you want to make sure that particular client always uses DPoP binding.
|
||||
|
||||
Note that this {project_name} switch maps to the switch `dpop_bound_access_tokens` introduced in the DPoP specification in client registration metadata.
|
||||
|
||||
In the following cases, {project_name} verifies the client sending the access token or the refresh token:
|
||||
|
||||
* A token refresh request is sent to the token endpoint with a holder-of-key refresh token. This verification is done only for public clients as described in the DPoP specification.
|
||||
For confidential clients, the verification is not done as client authentication with proper client credentials is in place to ensure that request comes from the legitimate client.
|
||||
For public clients, both access tokens and refresh tokens are DPoP bound. For confidential clients, only access tokens are DPoP bound.
|
||||
* A UserInfo request is sent to UserInfo endpoint with a DPoP bound access token.
|
||||
* A logout request is sent to a non-OIDC compliant {project_name} proprietary logout endpoint with a holder-of-key refresh token. This verification is done only for public clients as described above.
|
||||
* Request is sent to another {project_name} endpoint secured by the bearer token sent in the `Authorization` header. This applies for example to the admin REST or account REST endpoints.
|
||||
|
||||
{project_name} also provides the client policy executor `dpop-bind-enforcer`. With this executor, you can specify the following:
|
||||
|
||||
* Newly registered or updated OIDC clients are automatically configured with *Require DPoP bound tokens* switch to ON.
|
||||
* DPoP binding is done only for the refresh tokens, but not for access tokens. This binding is useful for public clients to increase security, so that the refresh token is DPoP bound and {project_name}
|
||||
requires DPoP in the request for the token request. However, the access token is not DPoP bound, which may be needed for example for compatibility reasons as the corresponding legacy resource servers
|
||||
(where access tokens are needed to be sent by the client application), cannot handle DPoP bound access tokens properly.
|
||||
* DPoP binding is enforced for the whole Authorization Code flow, which means that clients are enforced to send the `dpop_jkt` parameter in the initial OIDC/OAuth authentication requests.
|
||||
|
||||
For the details, see <<_client_policies, Client Policies>>, which contains general details on how to configure and set up client policies in your realm.
|
||||
|
||||
See https://datatracker.ietf.org/doc/html/rfc9449[OAuth 2.0 Demonstrating Proof of Possession (DPoP) specification] for more details about DPoP.
|
||||
|
||||
[NOTE]
|
||||
====
|
||||
{project_name} client adapters do not support DPoP holder-of-key token verification. {project_name} adapters treat access and refresh tokens as bearer tokens.
|
||||
====
|
||||
@ -1935,7 +1935,7 @@ scopePermissions.groups.view-description=Policies that decide if an administrato
|
||||
tokens=Tokens
|
||||
createFlow=Create flow
|
||||
encryptAssertionsHelp=Should SAML assertions be encrypted with client's public key?
|
||||
oAuthDPoPHelp=This enables support for Demonstrating Proof-of-Possession (DPoP) bound tokens. For public clients, both access and refresh tokens are bound to the key stored on the user agent. In order to prove the possession of the key, the user agent must send a signed proof alongside the token. For confidential clients, only access tokens are DPoP bound because, following the specification, refresh tokens are already sender-constrained by the associated authentication requirement.
|
||||
oAuthDPoPHelp=This enables support for Demonstrating Proof-of-Possession (DPoP) bound tokens. For public clients, both access and refresh tokens are bound to the key stored on the client. In order to prove the possession of the key, the client must send a signed proof alongside the token. For confidential clients, only access tokens are DPoP bound because, following the specification, refresh tokens are already sender-constrained by the associated authentication requirement.
|
||||
unsavedChangesConfirm=You have unsaved changes. Do you really want to leave the page?
|
||||
disabledOff=Disabled off
|
||||
membershipLdapAttributeHelp=Name of LDAP attribute on group, which is used for membership mappings. Usually it will be 'member'. However when 'Membership Attribute Type' is 'UID', then 'Membership LDAP Attribute' could be typically 'memberUid'.
|
||||
|
||||
@ -38,10 +38,11 @@ public class DPoPBindEnforcerExecutorFactory implements ClientPolicyExecutorPro
|
||||
AUTO_CONFIGURE, "Auto-configure", "If On, then the during client creation or update, the configuration of the client will be auto-configured to use DPoP bind token", ProviderConfigProperty.BOOLEAN_TYPE, false);
|
||||
|
||||
private static final ProviderConfigProperty ENFORCE_AUTHORIZATION_CODE_BINDING_TO_DPOP_KEY = new ProviderConfigProperty(
|
||||
ENFORCE_AUTHORIZATION_CODE_BINDING_TO_DPOP, "Enforce Authorization Code binding to DPoP key", "If On, then there is enforced authorization code binding to DPoP key. This means that parameter 'dpop_jkt' will be required in the OIDC/OAuth2 authentication requests and will be verified during token request if it matches DPoP proof. When this is false, it is still possible to use 'dpop_jkt' parameter, but it will not be required", ProviderConfigProperty.BOOLEAN_TYPE, false);
|
||||
ENFORCE_AUTHORIZATION_CODE_BINDING_TO_DPOP, "Enforce Authorization Code binding to DPoP key", "If On, then there is enforced authorization code binding to DPoP key. This means that parameter 'dpop_jkt' will be required in the OIDC/OAuth2 authentication requests and will be verified during token request if it matches DPoP proof. When this is false, it is still possible to use 'dpop_jkt' parameter, " +
|
||||
"which would be checked in the token request later, but 'dpop_jkt' parameter will not be required", ProviderConfigProperty.BOOLEAN_TYPE, false);
|
||||
|
||||
private static final ProviderConfigProperty ALLOW_ONLY_REFRESH_BINDING_PROPERTY = new ProviderConfigProperty(
|
||||
ALLOW_ONLY_REFRESH_BINDING, "Bind only refresh token for public client", "If On and the client is public the DPoP binding is enforced only for refresh token, this option is ignored if the DPoP is enforced in client settings or if the client is not public",
|
||||
ALLOW_ONLY_REFRESH_BINDING, "Bind only refresh token for public client", "If On and the client is public the DPoP binding is enforced only for refresh token. This option is ignored if the DPoP is enforced in client settings or if the client is not public",
|
||||
ProviderConfigProperty.BOOLEAN_TYPE, false);
|
||||
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user