From e56773fea37ae06b8099020daad7405612583d51 Mon Sep 17 00:00:00 2001 From: Chris Tran Date: Thu, 5 Dec 2024 22:13:02 +0000 Subject: [PATCH] feat: adds aud validation when validating jwt --- custom/lib/Auth.php | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/custom/lib/Auth.php b/custom/lib/Auth.php index 2ed4c78..c7365ca 100644 --- a/custom/lib/Auth.php +++ b/custom/lib/Auth.php @@ -6,7 +6,9 @@ use GuzzleHttp\Psr7\HttpFactory; use Firebase\JWT\JWT; use Firebase\JWT\CachedKeySet; +use OpenAPI\Client\Api\AppsApi; use OpenAPI\Client\ApiException; +use OpenAPI\Client\Model\AppInfo; use Phpfastcache\CacheManager; use InvalidArgumentException; use UnexpectedValueException; @@ -18,6 +20,7 @@ class Auth { private CachedKeySet $jwks; + private AppInfo $app; /** * Auth class that provides methods for validating JWTs and creating Magic Links. @@ -27,9 +30,11 @@ public function __construct(private string $appId, private Configuration $config $this->appId = $appId; $this->config = $config; + $appsApi = new AppsApi(); + $this->app = $appsApi->getApp($this->appId)->getApp(); + $httpClient = new Client(); $httpFactory = new HttpFactory(); - $cacheItemPool = CacheManager::getInstance('files'); $this->jwks = new CachedKeySet( "https://auth.passage.id/v1/apps/{$appId}/.well-known/jwks.json", @@ -48,25 +53,21 @@ public function __construct(private string $appId, private Configuration $config * * @return string User ID of the Passage user * @throws InvalidArgumentException JWT format is invalid - * @throws UnexpectedValueException Could not retrieve sub claim from token + * @throws UnexpectedValueException Could not validate aud claim or retrieve sub claim from token */ public function validateJwt(string $jwt): string { - $jwtSegments = explode('.', $jwt); - if (count($jwtSegments) !== 3) { - throw new InvalidArgumentException('Invalid JWT format'); - } - - $decodedHeader = JWT::urlsafeB64Decode($jwtSegments[0]); - $header = json_decode($decodedHeader); - - if (!$header->kid) { - throw new InvalidArgumentException('Missing kid in token'); + $decodedToken = JWT::decode($jwt, $this->jwks); + + $aud = (array) $decodedToken->aud; + $expectedAud = $this->app->getHosted() ? $this->appId : $this->app->getAuthOrigin(); + + if (!in_array($expectedAud, $aud)) { + throw new UnexpectedValueException('JWT audience does not match'); } - $decodedToken = JWT::decode($jwt, $this->jwks); $userId = $decodedToken->sub; - + if (!$userId) { throw new UnexpectedValueException('Could not retrieve sub claim from token'); }