Description
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
authorization-services
Describe the bug
When using the authorization functionality and checking permissions with permission_resource_matching_uri
enabled, if multiple resources match the same URI, the authorization process only considers one of these resources, leading to inconsistencies.
Use Case
Consider an app that manages cities. For each city in the app, a Keycloak resource is created to manage the URI:
/country/{country}/department/{department}/city/{city}
For example, a city would be represented by a Keycloak resource that has a URI like: /country/France/department/33/city/Bordeaux
.
Now, we want to create a root resource that matches all URIs and a country resource to manage all cities within a country.
The root resource manages the URI pattern: /*
The country resource manages the URI pattern: /country/France/*
.
When a user is granted access to the root resource, we would expect that any authorization request for any URI would be validated by Keycloak. However, in this scenario, having authorization for the root resource but not for the country or city resources, if these resources exist, results in a 403 Unauthorized error.
In our example, if a user with access to the root resource would ask authorization to the uri /country/France/department/33/city/Bordeaux
, it will receive a 403 Unauthorized error.
Version
24.0.5
Regression
- The issue is a regression
Expected behavior
The behavior should be the same when permission_resource_matching_uri
is false
and when permission_resource_matching_uri
is true
.
permission_resource_matching_uri
disabled
Assume that two resource (resourceA and resourceB) manages the same uri, we call /exampleUri
.
Assume a user U has permission on resourceA but has no permission on resourceB.
If the user U asks access to the uri /exampleUri
, authorization access will be granted.
permission_resource_matching_uri
enabled
We should have the same behavior as when permission_resource_matching_uri
is disabled.
Assume that resourceA manages pattern : /*
Assume that resourceB manages pattern : /examplePrefix/*
Both resources implicitly manages the uri : /examplePrefix/exampleUri
Assume a user U has permission on resourceA but has no permission on resourceB
If the user U asks access to the uri /examplePrefix/exampleUri
, authorization access should be granted.
Actual behavior
If we take the same example :
permission_resource_matching_uri
enabled
Assume that resourceA manages pattern : /*
Assume that resourceB manages pattern : /examplePrefix/*
Both resources implicitly manages : /examplePrefix/exampleUri
Assume a user U has permission on resourceA but has no permission on resourceB
If a user asks access to our /examplePrefix/exampleUri
, the authorization request will be in 403, unauthorized error.
This is due to the method getResourceListByUri
at this line of keycloak source code.
When permission_resource_matching_uri
is disabled, the method returns a list of resources.
But when permission_resource_matching_uri
is enabled, the method always returns a singleton list.
How to Reproduce?
- Create a resource-server
- On the resource server, create two resources :
- resourceA with uri :
/*
- resourceB with uri :
/country/myCountry
- resourceA with uri :
- Create a permission that gives access to your user on resourceA
- Call the authorization endpoint with :
- permission_resource_format: "uri"
- permission_resource_matching_uri: true
- permission:/country/myCountry/departement/myDepartment
Then you will get a 403.
Anything else?
This is slightly (but not exactly) similar to this discourse problem.
The problem has also be mentioned, under the form of a question, in stackoverflow.