Skip to content

Add FAPI 2.0 with DPoP to the OIDC and OAuth2 identity providers - #55204

Open
justin-tay wants to merge 1 commit into
keycloak:mainfrom
justin-tay:gh51393
Open

justin-tay wants to merge 1 commit into
keycloak:mainfrom
justin-tay:gh51393

Conversation

@justin-tay

Copy link
Copy Markdown
Contributor

Closes #51393

This adds FAPI 2.0 support (the DPoP aspect only, mTLS will be separate) to the OIDC and OAuth2 identity providers, so Keycloak can act as a FAPI 2.0 client when brokering to an upstream IdP.

Notable changes

  • PAR, signed request objects, DPoP bound access tokens (including server-supplied nonces) and response issuer (iss) validation
  • ID token signing alg and audience checks and issuer validation against the discovery endpoint
  • The ID token nonce is now verified from the token claim and generated nonces are 32 bytes instead of 16
  • Admin UI settings, docs and tests

Breaking changes for custom providers extending AbstractOAuth2IdentityProvider / OIDCIdentityProvider

  • createAuthorizationUrl(AuthenticationRequest) now returns URI instead of UriBuilder and throws IOException. Subclasses that tweaked the URL should override the new addAuthorizationParameters(request, parameters) instead. GoogleIdentityProvider is updated accordingly.
  • parseTokenInput(String, boolean) is now parseTokenInput(String, boolean, String expectedAlgorithm).
  • OIDCIdentityProvider.validateToken(String) is renamed to validateIdToken(String).
  • ID tokens and logout tokens without an exp claim are now rejected.
oidc-settings oidc-response-validation

Closes keycloak#51393

Signed-off-by: Justin Tay <49700559+justin-tay@users.noreply.github.com>
@justin-tay
justin-tay requested review from a team as code owners November 15, 2026 02:39
Copilot AI balanced review requested due to automatic review settings November 15, 2026 02:39

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Selecting the active realm key for each DPoP proof can break login and refresh flows after key rotation because existing codes and tokens remain bound to the original key.

1 open issue
What changed in this PR

Adds DPoP-based FAPI 2.0 client support to Keycloak’s OIDC and OAuth2 identity brokers, addressing #51393. Mutual TLS support remains separate.

Changes:

  • Adds pushed authorization requests, signed request objects, and DPoP proofs with nonce retries.
  • Strengthens state, issuer, token signature, audience, expiration, and nonce validation.
  • Adds Admin UI settings, documentation, and integration tests, and updates provider extension hooks.
File Description
testsuite/​integration-arquillian/​servers/​auth-server/​services/​testsuite-providers/​src/​main/​java/​org/​keycloak/​testsuite/​broker/​oidc/​TestKeycloakOidcIdentityProviderFactory.java Adapts the legacy test provider to the new parameter hook.
tests/​custom-providers/​src/​main/​resources/​META-INF/​services/​org.keycloak.protocol.ProtocolMapper Registers the wrong-nonce test mapper.
tests/​custom-providers/​src/​main/​java/​org/​keycloak/​tests/​providers/​broker/​oidc/​WrongNonceProtocolMapper.java Generates incorrect nonces for rejection tests.
tests/​custom-providers/​src/​main/​java/​org/​keycloak/​tests/​providers/​broker/​oidc/​TestKeycloakOidcIdentityProviderFactory.java Adapts the test provider to the new parameter hook.
tests/​base/​src/​test/​java/​org/​keycloak/​tests/​broker/​OidcBrokerLogoutTokenTest.java Tests logout-token validation.
tests/​base/​src/​test/​java/​org/​keycloak/​tests/​broker/​oidc/​KcOidcBrokerRequestObjectTest.java Tests signed request objects passed by value.
tests/​base/​src/​test/​java/​org/​keycloak/​tests/​broker/​oidc/​KcOidcBrokerFapi2DPoPTest.java Tests FAPI brokering and invalid-response rejection.
tests/​base/​src/​test/​java/​org/​keycloak/​tests/​broker/​oidc/​KcOidcBrokerFapi2DPoPMessageSigningTest.java Tests signed-request requirements and lifespan limits.
tests/​base/​src/​test/​java/​org/​keycloak/​tests/​broker/​oidc/​AbstractKcOidcBrokerFapi2Test.java Provides shared HTTPS and FAPI test configuration.
tests/​base/​src/​test/​java/​org/​keycloak/​tests/​broker/​OAuth2BrokerFapi2DPoPTest.java Tests DPoP nonce retries, token types, and state validation.
tests/​base/​src/​test/​java/​org/​keycloak/​tests/​broker/​KcOAuth2BrokerDPoPTest.java Tests OAuth2 brokering with DPoP and metadata import.
tests/​base/​src/​test/​java/​org/​keycloak/​tests/​admin/​identityprovider/​IdentityProviderOidcTest.java Tests new configuration validation rules.
services/​src/​main/​java/​org/​keycloak/​social/​google/​GoogleIdentityProvider.java Migrates Google-specific authorization parameters.
services/​src/​main/​java/​org/​keycloak/​broker/​oidc/​OIDCIdentityProviderFactory.java Imports new OIDC metadata settings.
services/​src/​main/​java/​org/​keycloak/​broker/​oidc/​OIDCIdentityProviderConfig.java Adds token algorithm and audience settings.
services/​src/​main/​java/​org/​keycloak/​broker/​oidc/​OIDCIdentityProvider.java Integrates DPoP requests and stronger token validation.
services/​src/​main/​java/​org/​keycloak/​broker/​oidc/​OAuth2IdentityProviderConfig.java Adds shared FAPI configuration and metadata validation.
services/​src/​main/​java/​org/​keycloak/​broker/​oidc/​AbstractOAuth2IdentityProvider.java Implements pushed requests, request objects, DPoP, and callback checks.
services/​src/​main/​java/​org/​keycloak/​broker/​oauth/​OAuth2IdentityProviderFactory.java Imports new OAuth2 metadata settings.
services/​src/​main/​java/​org/​keycloak/​broker/​oauth/​OAuth2IdentityProvider.java Uses DPoP-aware requests for user profiles.
js/​apps/​admin-ui/​test/​identity-providers/​oidc.spec.ts Tests OIDC FAPI settings and editability.
js/​apps/​admin-ui/​test/​identity-providers/​oauth2.spec.ts Tests new OAuth2 settings.
js/​apps/​admin-ui/​test/​identity-providers/​main.ts Separates form filling from provider creation.
js/​apps/​admin-ui/​src/​identity-providers/​add/​ResponseValidationSettings.tsx Adds shared response-validation controls.
js/​apps/​admin-ui/​src/​identity-providers/​add/​DiscoverySettings.tsx Separates metadata fields from editable client settings.
js/​apps/​admin-ui/​src/​identity-providers/​add/​DetailSettings.tsx Adds authentication and response-validation panels.
js/​apps/​admin-ui/​src/​identity-providers/​add/​AddOpenIdConnect.tsx Exposes validation settings during OIDC creation.
js/​apps/​admin-ui/​src/​identity-providers/​add/​AddOAuth2.tsx Exposes validation settings during OAuth2 creation.
js/​apps/​admin-ui/​maven-resources/​theme/​keycloak.v2/​admin/​messages/​messages_en.properties Adds labels and help text for new controls.
docs/​documentation/​server_admin/​topics/​identity-broker/​oidc.adoc Documents OIDC settings and FAPI configuration.
docs/​documentation/​server_admin/​topics/​identity-broker/​oauth2.adoc Documents OAuth2 request and DPoP settings.
core/​src/​main/​java/​org/​keycloak/​util/​DPoPGenerator.java Supports supplied signers and nonce claims.
core/​src/​main/​java/​org/​keycloak/​OID4VCConstants.java Reuses the shared request-object type constant.
core/​src/​main/​java/​org/​keycloak/​OAuthErrorException.java Adds the DPoP nonce-challenge error constant.
core/​src/​main/​java/​org/​keycloak/​OAuth2Constants.java Defines the shared request-object JWT type.

Review effort: Balanced


private String createDPoPProof(String method, String url, String accessToken, String nonce) {
String algorithm = getConfig().getDPoPSigningAlg();
KeyWrapper key = session.keys().getActiveKey(session.getContext().getRealm(), KeyUse.SIG, algorithm);

@keycloak-github-bot keycloak-github-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unreported flaky test detected, please review

@keycloak-github-bot

Copy link
Copy Markdown

Unreported flaky test detected

If the flaky tests below are affected by the changes, please review and update the changes accordingly. Otherwise, a maintainer should report the flaky tests prior to merging the PR.

org.keycloak.testsuite.cluster.JGroupsCertificateRotationClusterTest#testCoordinatorHasScheduleTask

Keycloak CI - Clustering IT

org.awaitility.core.ConditionTimeoutException: Assertion condition defined as a Lambda expression in org.keycloak.testsuite.cluster.JGroupsCertificateRotationClusterTest expected: <2> but was: <1> within 1 minutes.
	at org.awaitility.core.ConditionAwaiter.await(ConditionAwaiter.java:167)
	at org.awaitility.core.AssertionCondition.await(AssertionCondition.java:119)
	at org.awaitility.core.AssertionCondition.await(AssertionCondition.java:31)
	at org.awaitility.core.ConditionFactory.until(ConditionFactory.java:1160)
...

Report flaky test

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

FAPI 2.0 support for Native SSO/OIDC Broker

2 participants