From 822bdfb1669b80c6ca514a4c6d0be1938e5754b1 Mon Sep 17 00:00:00 2001 From: Elias Luhr Date: Mon, 1 Jul 2024 15:34:02 +0200 Subject: [PATCH] get pub key from cache --- README.md | 2 ++ src/helpers/KeycloakHelper.php | 62 ++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 src/helpers/KeycloakHelper.php diff --git a/README.md b/README.md index 8f9cc1c..f1f7603 100644 --- a/README.md +++ b/README.md @@ -366,6 +366,8 @@ return [ 'validationConstraints' => function (JwtTools $jwt) { return [ new SignedWith($jwt->buildSigner(Jwt::RS256), InMemory::plainText(getenv('KEYCLOAK_PUBLIC_KEY_FILE'))), + // You could also use this line if you do not want to use a separate public key file + // new SignedWith($jwt->buildSigner(Jwt::RS256), InMemory::plainText(KeycloakHelper::publicKeyFromIssuer(getenv('KEYCLOAK_ISSUER_URL')))), new IssuedBy(getenv('KEYCLOAK_ISSUER_URL')), new LooseValidAt(SystemClock::fromUTC()), ]; diff --git a/src/helpers/KeycloakHelper.php b/src/helpers/KeycloakHelper.php new file mode 100644 index 0000000..e71f2e4 --- /dev/null +++ b/src/helpers/KeycloakHelper.php @@ -0,0 +1,62 @@ +getCache(); + // Check if cache component does exist + if ($cache instanceof CacheInterface) { + $publicKey = $cache->getOrSet(__CLASS__ . '.publicKey', function () use ($issuerUrl) { + // Get public key from issuer url. Cache it if it exists. If there is an error or invalid public key. Do not cache + $publicKey = self::fetchPublicKeyFromIssuer($issuerUrl); + if (is_string($publicKey)) { + return $publicKey; + } + return false; + }, 3600); + + if (is_string($publicKey)) { + return $publicKey; + } + return null; + } + // If cache component does not exist. Fetch key directly + return self::fetchPublicKeyFromIssuer($issuerUrl); + + } + + protected static function fetchPublicKeyFromIssuer(string $issuerUrl): ?string + { + $client = new Client([ + 'baseUrl' => $issuerUrl + ]); + + $response = $client->get('')->send(); + + if ($response->getIsOk()) { + $publicKeyContent = $response->getData()['public_key'] ?? null; + } else { + $publicKeyContent = null; + } + + if (!empty($publicKeyContent)) { + // Build public key in format needed by lombucci package + $publicKey = '-----BEGIN PUBLIC KEY-----' . PHP_EOL . $publicKeyContent . PHP_EOL . '-----END PUBLIC KEY-----'; + } else { + $publicKey = null; + } + + return $publicKey; + } +}