8000 PolicyEnforcer sometimes looses provided adapterconfig while executing resource matching · Issue #9855 · keycloak/keycloak · GitHub
[go: up one dir, main page]

Skip to content

PolicyEnforcer sometimes looses provided adapterconfig while executing resource matching #9855

Closed

Description

@albert0815

Describe the bug

We use Keycloak policy enforcement in Quarkus microservices. Some resources we disable for policy enforcement using the application.properties. Sample:

quarkus.keycloak.policy-enforcer.paths.health.name=Health Check
quarkus.keycloak.policy-enforcer.paths.health.path=${quarkus.http.root-path}/q/health/*
quarkus.keycloak.policy-enforcer.paths.health.enforcement-mode=DISABLED

It seems that those configurations sometimes is lost. This seems to be the case because we sometimes experience 401/403 errors based on those resources even though they are explicitly excluded. It is not reproducible. While debugging the issue and checking the code I found the following which I assume could result in the problem which we are facing and hope you can help me analyzing further or maybe come up with a fix.

I think the logic in the matches method of the PathConfigMatcher could lead to the above described situation. There are a few things which seem like possible causes:

1. Removing entries from paths variable in

https://github.com/keycloak/keycloak/blob/main/adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/authorization/PolicyEnforcer.java#L276

My understanding of that section is that in case a cache entry expires it will be removed from the paths instance variable. That variable actually contains the initial list of entries which have been provided in the adapterConfig (from application.properties). I can't think of any situation in which this should happen. So I think this could be the reason for the behaviour which we are observing.

2. Different behaviour depending on * being in the path of the configuration or not

https://github.com/keycloak/keycloak/blob/main/adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/authorization/PolicyEnforcer.java#L270

If we provide a configuration in the application.properties it can happen that this configuration is being overriden by a resource in Keycloak. This is the case when the path contains a *. It will go into the section because there is * in the path and then retrieve the resouce from Keycloak. If something is found there that takes precedence over the configuration in the paths instance variable. In the case if the original configuration in application.properties would not contain a * in the path no request to Keycloak would be issued and therefore the entry in application.properties takes precedence. And in this case also the entry would never be removed from the paths variable since the removal is within the if statement.

3. Potentially a multithreading issue

https://github.com/keycloak/keycloak/blob/main/adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/authorization/PolicyEnforcer.java#L263

In the case that there is no entry in the cache when line 261 is being executed in thread A, but then in a different thread something is put into the cache with that key and now context switches again to thread A while executing line 263 the containsKey check will be true and null will be returned.

Version

15.0.2 (but is same in current version)

Expected behavior

Entries in the adapaterConfig which are provided to PolicyEnforcer should always be present and never get lost. Entries in adapterConfig should always take precedence over Keycloak resources.

Actual behavior

Entries in the adapaterConfig which are provided to PolicyEnforcer are being removed in certain circumstances. Entries in adapterConfig with a * can be overriden by Keycloak resources.

How to Reproduce?

I do not have a reproducing sample. The above description is based on my understanding of the code which might be wrong. I think to make it happen in real world it is some kind of multithreading issue which I was not able to reproduce. But it happens every now and then in our application and I hope you can help to identify the root cause even if above description and understanding of the code is not accurate.

Anything else?

No response

Activity

  1. pedroigor commented on Aug 11, 2022

    @pedroigor
    Contributor

    @albert0815 First of all, sorry for the delay. You're right about the #1 assumption.

    However, this only happens if the path you are configuring does not point a existent resource in Keycloak. For instance:

    quarkus.keycloak.policy-enforcer.paths.health.name=Health Check
    

    In any case, the change here makes sure that disabled paths are never invalidated even if they don't map to an existing resource.

  2. added this to the 20.0.0 milestone on Aug 11, 2022
  3. added a commit that references this issue on Aug 17, 2022
    7312ec3
  4. Repository owner moved this from Todo to Done in Keycloak: Quarkus distributionon Aug 17, 2022
  5. added a commit that references this issue on Aug 17, 2022
    15bbb46
  6. added a commit that references this issue on Sep 6, 2022
    446df90
  7. modified the milestones: 20.0.0, 19.0.2 on Sep 8, 2022
  8. added a commit that references this issue on Sep 8, 2022
    e37226f
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area/authorization-servicesAuthorization Services — UMA, policies, permissions, resource serverskind/bugCategorizes a PR related to a bugstatus/triage

Type

No type

Fields

No fields configured for issues without a type.

Projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions

0