-
Notifications
You must be signed in to change notification settings - Fork 8k
Lightweight access tokens for Admin REST API #32347
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Unreported flaky test detectedIf 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.model.session.UserSessionPersisterProviderTest#testPersistenceWithLoadKeycloak CI - Store Model Tests |
There was a problem hiding this 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
mposolda
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@graziang Thanks for the PR and the performance analysis! I would say let's go with this approach and we can later evaluate if there are any issues reported and do more performance optimizations as a follow-up if needed.
I've added some minor comments inside.
Besides that, is it possible to add some short notice to migration guide about changed setting of the security-admin-console and admin-cli clients? You can add that behaviour in the admin console should be effectively the same, but can be good to still mention it for the case that someone uses those clients for some other use-cases etc.
| try { | ||
| if (jwt.getIssuedFor().equals(Constants.ADMIN_CLI_CLIENT_ID) | ||
| || jwt.getIssuedFor().equals(Constants.ADMIN_CONSOLE_CLIENT_ID)) { | ||
| return hasRoleInModel(roles); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it possible to remove method hasRoleInModel now from this class?
| } | ||
|
|
||
| //get client session | ||
| ClientModel client = realm.getClientByClientId(issuedFor); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess it can still happen that userSession is null after this? Same for client and clientSession variables below? Is it possible to handle his better way than NullPointerException? Maybe it is OK to just add debug log message and not set anything into jwt for this case.
| } | ||
|
|
||
| //get client session | ||
| ClientModel client = adminsRealm.getClientByClientId(issuedFor); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same comment like the other place for userSession, client and clientSession null checks.
cfc290a to
9af33cf
Compare
Closes keycloak#31513 Signed-off-by: Giuseppe Graziano <[email protected]>
9af33cf to
1ea6ba1
Compare
Closes keycloak#31513 Signed-off-by: Giuseppe Graziano <[email protected]>
1ea6ba1 to
7882de1
Compare
There was a problem hiding this 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
Unreported flaky test detectedIf 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.webauthn.registration.passwordless.PwdLessPolicyJsInjectionTest#relyingPartyIdKeycloak CI - WebAuthn IT (chrome) org.keycloak.testsuite.forms.MultipleTabsLoginTest#expiredAuthenticationAction_currentCodeExpiredExecutionKeycloak CI - Forms IT (chrome) org.keycloak.testsuite.forms.ResetPasswordTest#resetPasswordWithSpacesInUsernameKeycloak CI - Forms IT (chrome) |
mposolda
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@graziang Thanks!
Closes #31513
Changes introduced by this PR to support lightweight access tokens for the admin REST APIs:
In
MgmtPermissions.initIdentity(), the presence of thesubfield in the token is evaluated to check if the access token is lightweight. If thesubis missing, the user session is retrieved, and the realm roles and client roles are resolved. All client roles of the user are resolved not just a subset. See the performance analysis for details.The workaround for the
security-admin-consoleandadmin-cliclients has been removed. To remove the workaround that was present both inMgmtPermissions.initIdentity()and inClientRegistrationAuth, a migration was necessary to enable the use of lightweight access tokens and to enable the full scope allowed for these clients. Enabling the full scope allowed is needed to resolve the client roles of the various realm clients in the master realm.A normal audience check for the admin REST APIs is not possible due to the
admin-fine-grained-authzfeature. With this feature enabled, the permissions to invoke the admin APIs can be granted based on client policies. Should we check the audience only in the case of this feature disabled or feature enabled and negative permission evaluation?Performance Analysis:
I conducted manual tests with the admin console, preloading 500 realms, and using both the admin user and a user with roles in 5 realms. With a non-lightweight token and with a different client than
security-admin-consoleandadmin-cli, the behavior remains the same.However, when using a lightweight token, it's necessary to resolve the user's roles, and this operation can be more expensive. Resolving the realm roles or client roles using
RoleResolveUtil.getResolvedRealmRoles(),RoleResolveUtil.getResolvedClientRoles()orRoleResolveUtil.getAllResolvedRealmRoles()first loads all the user's roles into cache with theRoleResolveUtil.getAndCacheResolvedRoles()method which based on the tests can cause a delay the first time it is invoked. The slowdown is noticeable only in the/serverinfocall which for the first time loads the user's roles in about 1.2 seconds (the same call with the previous behavior takes about 300ms). After this first load, the times of all other requests are in line with the previous behavior, or even better.One idea to optimize the loading of roles could be to add a query with a join between
USER_ROLE_MAPPINGandKEYCLOAK_ROLEto obtain only the list of roles for a client and a user or only realm roles for a user. However, this would require a greater impact on the classes and methods currently used to resolve roles.Alternatively, we could maintain the workaround and introduce only the changes from the first point when using lightweight access tokens for other clients.