-
-
Notifications
You must be signed in to change notification settings - Fork 694
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
The JWKS endpoint did not return a JSON object when keys are found in the cache #914
Comments
Fix for jpadilla#914
would you mind contribute the fix please? |
I've further investigated why the current tests do not raise this error. Put the conclusions in the PR, but I'm adding them here for easier access to anyone falling into the issue. I've investigated why it does not, and the root cause seems to be that in fetch_data, the cache is not fed with a PyJWKSet but with the dict directly read from the URL. As the cache is not the expected type but a dict, the get_jwk_set function obtains a dict from the cache, and the test passes. In my case I was feeding the cache in the client directly from an externally stored JWKS, to avoid the fetch from the URL. To do so, I manually created the PyJWKSetCache object and fed it with a PyJWKSet. That's why in my case the cache contained the expected data type and my code failed with the error. Heres's the result of my code inspection: First time the get_jwk_set is called, it will get None from the cache and call fetch_data. This is what in my opinion does not honor the declared data types in the type hints:
Then the JWKSetCache put method that should receive a PyJWKSet as per the type hint will receive a dictionary:
And that dictionary will find its way through to the final object stored in the cache:
Then, the JWKSetCache class will blindly return the dict instead of the PyJWKSet.
And finally the get_jwk_set always gets a dict wether it takes the data from the URL or from the cache
Any code expecting to receive the PyJWKSet type from the cache, or any code which as in my case feeds the cache in other way than through a fetch_data call will fail. The code in the PR fixed the problem declared in this issue without impacting any other current use of the module, as both the received and returned types of the function are preserved and no other parts of the module are changed. However, it does no fix use cases that use fetch_data and access the cache directly instead of through the fixed get_jwk_set. |
Additionally to the tests passing because of the casual coherence between fetch_data and get_jwk_set in putting a dictionary in the cache, I've found because of how test pyjwt/tests/test_jwks_client.py Line 222 in 95638cf
This is most probably happening, though I did not test them all, with all the other test functions that involve two calls to the same method of the same object with the same parameter values. Adding a new test like this, produces the expected result of reproducing this issue:
This test fails with the error mentioned in this issue using the existing code, and works with the code in the PR. Will add this change to the PR. |
This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 7 days |
This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 7 days |
When the
jwks_client.get_jwk_set
function finds the keys in the cache, it gets a PyJWKSet object, if not, it performs a fech and gets a JSON object. In both cases it checks if the data is a Dictionary, causing the check to fail when the data was retrieved from the cache.pyjwt/jwt/jwks_client.py
Line 68 in 95638cf
The right code would return the object found in the cache.
The text was updated successfully, but these errors were encountered: