pac4j-oidc with Keycloak 25+: Problem with ID token after refresh

45 views
Skip to first unread message

Ralf Wagner

unread,
May 28, 2025, 4:33:57 AMMay 28
to Pac4j development mailing list
Hi,

I'm using pac4j-oidc 5.7 and Keycloak as IDP in a project.
Keycloak has changed the behaviour for refresh tokens with version 25.
It adheres now more closely to the OpenID 1.0 specification with errata set 2 which states that the ID token that is returned after the refresh "it SHOULD NOT have a nonce Claim, even when the ID Token issued at the time of the original authentication contained nonce"

So Keycloak only adds the nonce parameter to the first issued ID token.
This leads to a problem in pac4j-oidc, as the nonce is checked each time an ID token is issued. The refresh is not working properly, but as the user is still logged in to Keycloak, pac4j is able to recover from the problem by logging in again which in our case leads (apart from the additional round trip to Keycloak) to a re-initialization of the application, i.e. all information the user has entered so far is lost.

Mitigations:
- Switching off using a nonce in the configuration "solves" the problem, as the nonce check is no longer performed.
- Keycloak offers enabling a backwards compatible behaviour without explicitely stating, how long this is supported.

The same behaviour occurs with the latest 6.1.2 version of pac4j-oidc.

Proposed change:
- Only performing the nonce check during a refresh, when the nonce is actual present, as the OIDC specification states the ID token "SHOULD NOT have a nonce Claim, even when the ID Token issued at the time of the original authentication contained nonce; however, if it is present, its value MUST be the same as in the ID Token issued at the time of the original authentication"

References:
Keycloak release notes:
OpenID Specification


Regards,
Ralf

Jérôme LELEU

unread,
May 28, 2025, 8:41:05 AMMay 28
to Ralf Wagner, Pac4j development mailing list
Hi,

This perfectly makes sense.
Can you submit a PR to fix the issue?
Thanks.
Best regards,
Jérôme


--
You received this message because you are subscribed to the Google Groups "Pac4j development mailing list" group.
To unsubscribe from this group and stop receiving emails from it, send an email to pac4j-dev+...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/pac4j-dev/c94def84-8bfb-4dc0-854c-53fc2fadd9e8n%40googlegroups.com.

Ralf Wagner

unread,
May 28, 2025, 1:13:46 PMMay 28
to Pac4j development mailing list
Hi,

ok, I'll try. This may take a couple of days.

Best regards,
Ralf

Alexandre Pique

unread,
Sep 15, 2025, 1:28:14 AMSep 15
to Pac4j development mailing list
Hi,

I have the same issue with this IdP :  https://demo.duendesoftware.com/ which doesn't return a nonce in the refreshed id_token.
I want try to help for this issue.

It is not easy to check the nonce if present because in the org.pac4j.oidc.profile.creator.TokenValidator#validate method, there is only the token and the validator, and the idTokenValidator is an external code, hard to change it.

I thought about a configuration.isUseNonceOnRefresh() to use here https://github.com/pac4j/pac4j/blob/master/pac4j-oidc/src/main/java/org/pac4j/oidc/profile/creator/OidcProfileCreator.java#L118 to activate or not the nonce check.

I could add a credentials.setRefreshedCredentials(true) flag after refreshing the credentials un  OidcClient.renewUserProfile method here :
Then in the OidcProfileCreator#create(final CallContext ctx, final Credentials credentials) method, if the credentials.isRefreshedCredentials() and configuration.isUseNonceOnRefresh(), I will set nonce = null

Are you ok with that ?
Best regards,
Alexandre

Alexandre Pique

unread,
Sep 15, 2025, 1:28:14 AMSep 15
to Pac4j development mailing list

Hi,

I have the same issue with this IdP :  https://demo.duendesoftware.com/ which doesn't return a nonce in the refreshed id_token.

I want try to help for this issue.

It is not easy to check the nonce if present because in the org.pac4j.oidc.profile.creator.TokenValidator#validate method, there is only the token and the validator, and the idTokenValidator is an external code, hard to change it.

I thought about a configuration.isUseNonceOnRefresh() to use here https://github.com/pac4j/pac4j/blob/master/pac4j-oidc/src/main/java/org/pac4j/oidc/profile/creator/OidcProfileCreator.java#L118 to activate or not the nonce check.

I could add a credentials.setRefreshedCredentials(true) flag after refreshing the credentials un  OidcClient.renewUserProfile method here :

https://github.com/pac4j/pac4j/blob/master/pac4j-oidc/src/main/java/org/pac4j/oidc/client/OidcClient.java#L84

Then in the OidcProfileCreator#create(final CallContext ctx, final Credentials credentials) method, if the credentials.isRefreshedCredentials() and configuration.isUseNonceOnRefresh(), I will set nonce = null

Are you ok with that ?

Best regards,

Alexandre



Jérôme LELEU

unread,
Sep 15, 2025, 2:10:22 AMSep 15
to Alexandre Pique, Pac4j development mailing list
Hi,

Updating the code here is not that easy.

But what you propose makes sense to me: a configuration flag + mark the OidcCredentials as refreshed.

Go ahead and let me know.

Thanks.
Best regards,
Jérôme


Reply all
Reply to author
Forward
0 new messages