Skip to content

UMA IS_ADMIN filter breaks ticket finding #48324

@erdoganege

Description

@erdoganege

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

No response

Describe the bug

Hello,

I think this new IS_ADMIN UMA permission ticket filter broke the caching functionality.
The MR: #47210
I'm talking about specifically this change: https://github.com/keycloak/keycloak/pull/47210/changes#diff-1e921492f31a55b4f93aaafdc92b2107801175e16b15e895108b213b9211d037R90

We have the following use case in our project as an ADMIN API: We want to retrieve all granted tickets within the system independently from their owner, requester, resource servers or anything else. This is what we do:

  1. We retrieve all Resource Servers in the system
  2. Iterate over the Resource Servers, and pull their tickets with (filters include IS_ADMIN=true, because we want to retrieve all tickets with the current user which is not either owner or requester):
    ticketStore.find(rs, filters, null, null)

The above change causes Keycloak to pull ALL tickets independently from their actual resource servers, because it does not put this one:

predicates.add(builder.equal(root.get("resourceServer").get("id"), resourceServer.getId()));

Then, if the first resource server is not the ticket's corresponding resource server, cache sets this ticket id as "not existing". So, when the actual resource server is queried in the next iteration, cache directly returns null, so we don't receive the ticket from this function call.

I think this should have been kept without touched:

if (resourceServer != null) {
            predicates.add(builder.equal(root.get("resourceServer").get("id"), resourceServer.getId()));

And, all other IS_ADMIN logic should be inside a separate if check.

Version

26.5.7

Regression

  • The issue is a regression

Expected behavior

Expected behavior is:
filter contains IS_ADMIN=true

When I run ticketStore.find(rs, filter, null, null), it should only care about the tickets that belong to that RS, not all tickets. So that, it won't do some caching for tickets that do not belong to that RS. In other words,

This should be added regardless of IS_ADMIN filter when resource server is not null:

predicates.add(builder.equal(root.get("resourceServer").get("id"), resourceServer.getId()));

Actual behavior

filter contains IS_ADMIN=true

When I run ticketStore.find(rs, filter, null, null), the StoreFactoryCacheSession sets a ticket as non-existing ticket in case resource servers are not matched.

How to Reproduce?

  1. Create two resource servers
  2. Grant a permission which belongs to first resource server (RS1)
  3. Set filters Granted=True and IS_ADMIN=True
  4. Call ticketStore.find(RS2, filter, null, null)
  5. Call ticketStore.find(RS1, filter, null, null)

You won't see the granted ticket.

Anything else?

No response

Metadata

Metadata

Assignees

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions