Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@rmartinc
Copy link
Contributor

Closes #43734

PR to check if offline_access is still allowed when doing a refresh token. The PR just returns the error and maintains the session (it follows the same behavior that is used for all the other similar exceptions). If you think The PR should remove the session or similar just let me know. Test added.

Copy link
Contributor

@ahus1 ahus1 left a comment

Choose a reason for hiding this comment

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

Thank you for the PR. See some review notes below.

Could you please add also a check for the token introspection so that an access token for an offline session is considered invalid if the offline scope doesn't exist any more? Thanks!

Comment on lines 236 to 240
if (oldTokenScope != null && parseScopeParameter(oldTokenScope).anyMatch(s -> OAuth2Constants.OFFLINE_ACCESS.equals(s))
&& clientSessionCtx.getClientScopesStream().noneMatch(s -> OAuth2Constants.OFFLINE_ACCESS.equals(s.getName()))) {
// offline access needed but scope is not allowed
throw new OAuthErrorException(OAuthErrorException.INVALID_SCOPE, "Invalid scope: " + OAuth2Constants.OFFLINE_ACCESS);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

I see that even for lightweight tokens the scope is always present, so I assume there is never the case of oldTokenScope being null.

I was briefly wondering if there would be the the need to handle any other removed scope. When trying this out, I found that any removed scope is then removed on the next token refresh, which is IMHO graceful enough and sufficient.

Copy link
Contributor Author

@rmartinc rmartinc Oct 27, 2025

Choose a reason for hiding this comment

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

The normal scopes are filtered when calculating the scopes in the DefaultClientSessionContext. The requested scopes are limited to ones the client has (without dynamic scopes here). So, the refresh is allowed but with less scopes (the removed ones are not added, it's the same for the user). So I think that part is OK, the response is just limited to the scopes that are still assigned. I would not change this behavior.

For offline_access is a bit different, because the offline session is not valid anymore for this client. Returning an error makes sense IMO. The problem was that we were never checking this. The session was offline, inherited by the new refresh and nothing checked the scope was not present anymore.

I'm going to remove the oldTokenScope != null. I think that you are right, it will be empty string in the worst case.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done! Let's see the tests...

Copy link
Contributor Author

@rmartinc rmartinc Oct 28, 2025

Choose a reason for hiding this comment

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

Sorry! I didn't read the check about introspection. Doing it right now.

Copy link

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

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

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.federation.ldap.LDAPProvidersIntegrationTest#updateLDAPUsernameTest

Keycloak CI - Base IT (5)

org.keycloak.testsuite.runonserver.RunOnServerException: java.lang.NullPointerException
	at org.keycloak.testsuite.client.KeycloakTestingClient$Server.fetchString(KeycloakTestingClient.java:185)
	at org.keycloak.testsuite.federation.ldap.LDAPProvidersIntegrationTest.updateLDAPUsernameTest(LDAPProvidersIntegrationTest.java:1656)
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
	at java.base/java.lang.reflect.Method.invoke(Method.java:580)
...

Report flaky test

@ahus1
Copy link
Contributor

ahus1 commented Oct 27, 2025

@rmartinc - did you see my comment above, and what's your take on this?

Could you please add also a check for the token introspection so that an access token for an offline session is considered invalid if the offline scope doesn't exist any more? Thanks!

@rmartinc
Copy link
Contributor Author

@ahus1 @graziang I have changed this a bit. I created a utility method in UserSessionUtil to check if the offline_access is still valid for the client session. This way it can be used for both, introspection and refresh. I have changed also a bit the error messages and I think that now they make more sense in both endpoints. Let's see the CI, I have just run locally the oauth and oidc tests.

Copy link
Contributor

@graziang graziang left a comment

Choose a reason for hiding this comment

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

@rmartinc thanks!

@rmartinc
Copy link
Contributor Author

If you think that it's OK please re-run the failed CI. It should be unrelated.

Copy link
Contributor

@ahus1 ahus1 left a comment

Choose a reason for hiding this comment

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

Thank you for this change!

@ahus1
Copy link
Contributor

ahus1 commented Oct 28, 2025

@rmartinc - let me know if I should merge this one, or if anyone else from your team should review it.

@rmartinc
Copy link
Contributor Author

@graziang already approved, so I think we are OK to merge it. I'll prepare the backports later.

@ahus1 ahus1 merged commit e0c1f2e into keycloak:main Oct 28, 2025
86 of 88 checks passed
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.

Refresh token allowed for offline session even the related scope is removed

3 participants