Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@
"cakephp/cakephp": "^4.4",
"cakephp/cakephp-codesniffer": "^4.0",
"firebase/php-jwt": "^6.2",
"phpunit/phpunit": "^8.5 || ^9.3"
"phpunit/phpunit": "^8.5 || ^9.3",
"symfony/cache": "^5.4 || ^6.0"
Copy link
Member

Choose a reason for hiding this comment

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

Why do we need this dependency?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

see the discussion here:

#535 (comment)

this was rebased / reopened as github closed it beeing stale for a while.

Copy link
Member

Choose a reason for hiding this comment

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

OK, so its the PSR6 vs PSR16 compatibility shims that we actually need. While I don't love the additional dependency I also don't relish maintaining adapter code for a low-frequency use feature. We'll should include the additional dependencies required in the documentation and raise an error with instructions to install the required dependencies if they don't exist.

},
"suggest": {
"cakephp/orm": "To use \"OrmResolver\" (Not needed separately if using full CakePHP framework).",
Expand Down
19 changes: 18 additions & 1 deletion src/Authenticator/JwtAuthenticator.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,19 @@

use ArrayObject;
use Authentication\Identifier\IdentifierInterface;
use Cake\Cache\Cache;
use Cake\Http\Client;
use Cake\Utility\Security;
use Exception;
use Firebase\JWT\CachedKeySet;
use Firebase\JWT\JWK;
use Firebase\JWT\JWT;
use Firebase\JWT\Key;
use Laminas\Diactoros\RequestFactory;
use Psr\Http\Message\ServerRequestInterface;
use RuntimeException;
use stdClass;
use Symfony\Component\Cache\Adapter\Psr16Adapter;

class JwtAuthenticator extends TokenAuthenticator
{
Expand All @@ -41,6 +46,7 @@ class JwtAuthenticator extends TokenAuthenticator
'secretKey' => null,
'subjectKey' => IdentifierInterface::CREDENTIAL_JWT_SUBJECT,
'jwks' => null,
'jwksCache' => null,
];

/**
Expand Down Expand Up @@ -149,7 +155,18 @@ protected function decodeToken(string $token): ?object
{
$jsonWebKeySet = $this->getConfig('jwks');
if ($jsonWebKeySet) {
$keySet = JWK::parseKeySet($jsonWebKeySet);
$jsonWebKeySetCache = $this->getConfig('jwksCache');
if ($jsonWebKeySetCache) {
$keySet = new CachedKeySet(
$jsonWebKeySet,
new Client(),
new RequestFactory(),
new Psr16Adapter(Cache::pool($jsonWebKeySetCache)),
Copy link
Member

Choose a reason for hiding this comment

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

Given that symfony/cache is an optional dependency the existence of the Psr16Adapter class should be checked first and in case of failure show a message stating which package the dev should include in their app.

3000
);
} else {
$keySet = JWK::parseKeySet($jsonWebKeySet);
}

return JWT::decode(
$token,
Expand Down