Skip to content
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

feat: add cached keyset #397

Merged
merged 47 commits into from
Apr 27, 2022
Merged

feat: add cached keyset #397

merged 47 commits into from
Apr 27, 2022

Conversation

bshaffer
Copy link
Collaborator

@bshaffer bshaffer commented Feb 8, 2022

see #384

Adds CachedKeySet to automatically cache and fetch from a JWK Set URI. Features:

  1. Fetch the JWK set from the JWKS URL using the HTTP Client / HTTP Client factory which you pass in
  2. Cache the results using the Cache Item Pool you pass in
  3. Refresh the results of the cache if a kid is requested which doesn't exist (automatic key rotation)
  4. Allows for a ratelimit on invalid keys to ensure the JWKS URL is not spammed (default 10 requests per second when enabled)

Usage:

use Firebase\JWT\CachedKeySet;
use Firebase\JWT\JWT;

$keySet = new CachedKeySet(
    'https://www.gstatic.com/iap/verify/public_key-jwk', // your JWK URI
    new GuzzleHttp\Client(),                             // your PSR-7 HTTP client
    new GuzzleHttp\Psr\HttpFactory(),                    // your PSR-18 HTTP factory
    Phpfastcache\CacheManager::getInstance('files')      // your PSR-6 Cache client
);

$decoded = JWT::decode($jwt, $keySet);
$verified = JWT::verify($jwt, $keySet);

@bshaffer bshaffer added the v6.1 label Feb 8, 2022
@bshaffer bshaffer marked this pull request as ready for review February 9, 2022 20:06
@bshaffer
Copy link
Collaborator Author

From @swiffer in another issue:

Hi @bshaffer - first sorry for late response and thanks a lot for initial implementation.
Coming from CakePHP and trying to use the new functionality there isn't that easy.
There are to PSR for Caching (6 + 16). CakePHP only bundles a SimpleCache (PSR 16) compatible cache.
Any reason why you've choosen one over the other?
Symfony provides a class of converting caches back and forth via Cache adapter classes so this could be a viable solution: https://symfony.com/doc/current/components/cache/psr6_psr16_adapters.html

I'm replying here to keep it in this thread for review.

I do not have a reason for choosing PSR-6 over PSR-16. If there's a strong argument to supporting one over the other (or both) I'm all ears.

Why is it difficult to implement in CakePHP? Does the minimum requirement of PHP 8.0 have something to do with it, or is it because you're using PSR-16 instead?

@swiffer
Copy link

swiffer commented Feb 19, 2022

cakephp/authentication 2.9.0 currently targets CakePHP 4.0 which requires >= PHP 7.2. this will be raised to PHP 7.4 in the next minor of CakePHP and PHP 8.0 in CakePHP 5.0. Therefore maybe it'll take some time until it can actually be used in the cakephp/authentication plugin but should work out. It's more that CakePHP only has a PSR 16 compatible cache implementation and introducing additional dependencies is increasing complexity.

}
}

if (!isset($this->keySet[$keyId])) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this code is currently not proof against ddos attacks via key spamming, or is it?

this scenario was described here: https://github.com/auth0/node-jwks-rsa#rate-limiting

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, it does not. We can add this to the cache without too much issue, however. I'll take a look. Thanks for pointing this out.

@bshaffer
Copy link
Collaborator Author

cakephp/authentication 2.9.0 currently targets CakePHP 4.0 which requires >= PHP 7.2.

I can cut a release with the minimum version at PHP 7.x (probably 7.1).

It's more that CakePHP only has a PSR 16 compatible cache implementation

This is a design decision by CakePHP, and doesn't really indicate so much what would be better for this repo. So unless it's possible to support both (which would require PHP 8.0 union types), I'd prefer to stick with PSR-6 unless there's a better argument to switch.

Copy link

@mortenhauberg mortenhauberg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've made a few minor suggestions.
Some might call them nitpicks - feel free to ignore them 😃

I would like to bump phpspec/prophecy-phpunit to v2, though, but that would break support for PHP 7.1 and 7.2.
Maybe you want to consider dropping support for those versions by now anyway since they've been unsupported for a while.

oiAN8kiFgGN9mrIoOh0QxkSP3Nddqqy8@2x

That would remove the deprecation warnings from PHPUnit and would be as simple as bumping the version and adding a trait in tests/CachedKeySetTest.php.

I can do that if you'd like.

Btw, I can see a bunch of old issues still being open.
Let me know if you like some help with those 🙂

README.md Outdated Show resolved Hide resolved
src/CachedKeySet.php Outdated Show resolved Hide resolved
src/CachedKeySet.php Outdated Show resolved Hide resolved
bshaffer and others added 3 commits April 13, 2022 14:39
Co-authored-by: Morten Hauberg-Lund <[email protected]>
Co-authored-by: Morten Hauberg-Lund <[email protected]>
Co-authored-by: Morten Hauberg-Lund <[email protected]>
@bshaffer
Copy link
Collaborator Author

@mortenhauberg Thanks for your review! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). For more information, open the CLA check for this pull request.

As for dropping support for PHP 7.1 and 7.2, I cringe at the idea of leaving some developers in the lurch because of testing libraries. If I'm going to drop PHP support, I want a better reason than that. And truthfully, the very end of 2020 (When 7.2 dropped support) was less than a year and a half ago, which is not very long in the relatively slow moving world of PHP.

@mortenhauberg
Copy link

@bshaffer CLA signed 👍🏻

I didn't necessarily mean for you to bump the supported versions now, and I do agree that doing it for the sake of a few tests is a bad reason.

I can also see that you still have users stuck on older versions. #399 (comment)

So I totally see your point 😊
But 7.1/7.2/7.3 is EOL, and at some point, you should probably drop support.
Anyway, it's not my call, and I'm happy if I could help move this forward.

Please let me know if there's anything else I can do

@glen-84
Copy link

glen-84 commented Apr 14, 2022

Despite the fact that we're on PHP 7.0, I actually agree with dropping support for EOL versions of PHP.

We shouldn't be using this version for many reasons, and if libraries don't drop support, then they're essentially enabling the use of potentially insecure software. This is even more relevant for a library dealing with aspects of security.

Yes, backporting one or two features to 6.0.x would be useful to us, but that's ultimately "our problem" – in the case of the linked issue, we can either stick with RSA, or consider backporting it ourselves (with or without an official 6.0.x release, though that would be nice).

Copy link

@dwsupplee dwsupplee left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a few minor notes so far, still working through the core of the logic in the CacheKeySet and the tests.

README.md Outdated Show resolved Hide resolved
README.md Outdated Show resolved Hide resolved
README.md Outdated Show resolved Hide resolved
README.md Outdated Show resolved Hide resolved
src/CachedKeySet.php Outdated Show resolved Hide resolved
src/CachedKeySet.php Outdated Show resolved Hide resolved
@bshaffer bshaffer merged commit 2308363 into main Apr 27, 2022
@bshaffer bshaffer deleted the add-cached-keyset branch April 27, 2022 22:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants