keycloak / keycloak

Open Source Identity and Access Management For Modern Applications and Services

Home Page:https://www.keycloak.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

NPE in checkAndBindMtlsHoKToken on Token Refresh when using SuppressRefreshTokenRotationExecutor and Certificate Bound Token

tnorimat opened this issue · comments

Before reporting an issue

  • I have read and understood the above terms for submitting issues, and I understand that my issue may be closed without action if I do not follow them.

Area

oidc

Describe the bug

When using both SuppressRefreshTokenRotationExecutor and Certificate Bound Token, checkAndBindMtlsHoKToken method occurs NPE on Token Refresh request.

Due to the issue, Keycloak 23.0.0 cannnot pass conformace tests (Test Name: fapi1-advanced-final-refresh-token) of Open Finance Brasil FAPI 1.0 (Open Banking Brasil FAPI 1.0 was renamed).

Version

23.0.0

Expected behavior

When using both SuppressRefreshTokenRotationExecutor and Certificate Bound Token, checkAndBindMtlsHoKToken method does not occur NPE on Token Refresh request and returns a token response without a refreshed refresh token.

Actual behavior

When using both SuppressRefreshTokenRotationExecutor and Certificate Bound Token, checkAndBindMtlsHoKToken method occurs NPE on Token Refresh request.

How to Reproduce?

  1. Apply to a client Certificate Bound Token by HolderOfKeyEnforcerExecutor
  2. Apply to the client SuppressRefreshTokenRotationExecutor
  3. The client sends a token request with a X.509 client certificate and receive a token response with a certificate-bound access and refresh tokens.
  4. The client sends a token refresh request with the X.509 client certificate

Anything else?

No response

In TokenEndpoint.refreshTokenGrant ,

            session.clientPolicy().triggerOnEvent(new TokenRefreshResponseContext(formParams, responseBuilder));

            checkAndBindMtlsHoKToken(responseBuilder, clientConfig.isUseRefreshToken());
            checkAndBindDPoPToken(responseBuilder, clientConfig.isUseRefreshToken() && (client.isPublicClient() || client.isBearerOnly()), Profile.isFeatureEnabled(Profile.Feature.DPOP));

should be

            checkAndBindMtlsHoKToken(responseBuilder, clientConfig.isUseRefreshToken());
            checkAndBindDPoPToken(responseBuilder, clientConfig.isUseRefreshToken() && (client.isPublicClient() || client.isBearerOnly()), Profile.isFeatureEnabled(Profile.Feature.DPOP));

            session.clientPolicy().triggerOnEvent(new TokenRefreshResponseContext(formParams, responseBuilder));