diff --git a/composer.json b/composer.json index 541c6716f..9b0be56d3 100644 --- a/composer.json +++ b/composer.json @@ -10,7 +10,7 @@ }, "require": { "php": ">=5.6", - "firebase/php-jwt": "~5.0", + "firebase/php-jwt": "^6.0", "guzzlehttp/guzzle": "^6.2.1|^7.0", "guzzlehttp/psr7": "^1.7|^2.0", "psr/http-message": "^1.0", diff --git a/src/OAuth2.php b/src/OAuth2.php index 5b6b4ec74..e37f977b7 100644 --- a/src/OAuth2.php +++ b/src/OAuth2.php @@ -18,6 +18,7 @@ namespace Google\Auth; use Firebase\JWT\JWT; +use Firebase\JWT\Key; use Google\Auth\HttpHandler\HttpClientCache; use Google\Auth\HttpHandler\HttpHandlerFactory; use GuzzleHttp\Psr7\Query; @@ -380,7 +381,7 @@ public function __construct(array $config) * `\InvalidArgumentException`. * * @param string $publicKey The public key to use to authenticate the token - * @param array $allowed_algs List of supported verification algorithms + * @param string $allowed_alg The supported verification algorithm * @throws \DomainException if the token is missing an audience. * @throws \DomainException if the audience does not match the one set in * the OAuth2 class instance. @@ -390,14 +391,14 @@ public function __construct(array $config) * @throws ExpiredException If the token has expired. * @return null|object */ - public function verifyIdToken($publicKey = null, $allowed_algs = array()) + public function verifyIdToken($publicKey = null, $allowed_alg) { $idToken = $this->getIdToken(); if (is_null($idToken)) { return null; } - $resp = $this->jwtDecode($idToken, $publicKey, $allowed_algs); + $resp = $this->jwtDecode($idToken, $publicKey, $allowed_alg); if (!property_exists($resp, 'aud')) { throw new \DomainException('No audience found the id token'); } @@ -1377,12 +1378,12 @@ private function coerceUri($uri) /** * @param string $idToken * @param string|array|null $publicKey - * @param array $allowedAlgs + * @param string $allowedAlg * @return object */ - private function jwtDecode($idToken, $publicKey, $allowedAlgs) + private function jwtDecode($idToken, $publicKey, $allowedAlg) { - return JWT::decode($idToken, $publicKey, $allowedAlgs); + return JWT::decode($idToken, new Key($publicKey, $allowedAlg)); } private function jwtEncode($assertion, $signingKey, $signingAlgorithm, $signingKeyId = null) diff --git a/tests/Credentials/ServiceAccountCredentialsTest.php b/tests/Credentials/ServiceAccountCredentialsTest.php index af8896388..944393c1c 100644 --- a/tests/Credentials/ServiceAccountCredentialsTest.php +++ b/tests/Credentials/ServiceAccountCredentialsTest.php @@ -19,6 +19,7 @@ use DomainException; use Firebase\JWT\JWT; +use Firebase\JWT\Key; use Google\Auth\ApplicationDefaultCredentials; use Google\Auth\Credentials\ServiceAccountCredentials; use Google\Auth\Credentials\ServiceAccountJwtAccessCredentials; @@ -800,7 +801,7 @@ public function testJwtAccessFromApplicationDefault() $token = str_replace('Bearer ', '', $metadata['authorization'][0]); $key = file_get_contents(__DIR__ . '/../fixtures3/key.pub'); - $result = JWT::decode($token, $key, ['RS256']); + $result = JWT::decode($token, new Key($key, 'RS256')); $this->assertEquals($authUri, $result->aud); } diff --git a/tests/OAuth2Test.php b/tests/OAuth2Test.php index 5b9719279..b553b9023 100644 --- a/tests/OAuth2Test.php +++ b/tests/OAuth2Test.php @@ -19,6 +19,7 @@ use DomainException; use Firebase\JWT\JWT; +use Firebase\JWT\Key; use Google\Auth\OAuth2; use GuzzleHttp\Psr7\Query; use GuzzleHttp\Psr7\Utils; @@ -450,7 +451,10 @@ public function testCanHS256EncodeAValidPayloadWithSigningKeyId() $testConfig['signingKeyId'] = 'example_key_id2'; $o = new OAuth2($testConfig); $payload = $o->toJwt(); - $roundTrip = JWT::decode($payload, $keys, array('HS256')); + $roundTrip = JWT::decode($payload, array( + 'example_key_id1' => new Key('example_key1', 'HS256'), + 'example_key_id2' => new Key('example_key2', 'HS256') + )); $this->assertEquals($roundTrip->iss, $testConfig['issuer']); $this->assertEquals($roundTrip->aud, $testConfig['audience']); $this->assertEquals($roundTrip->scope, $testConfig['scope']); @@ -468,7 +472,10 @@ public function testFailDecodeWithoutSigningKeyId() $payload = $o->toJwt(); try { - JWT::decode($payload, $keys, array('HS256')); + JWT::decode($payload, array( + 'example_key_id1' => new Key('example_key1', 'HS256'), + 'example_key_id2' => new Key('example_key2', 'HS256') + )); } catch (\Exception $e) { // Workaround: In old JWT versions throws DomainException $this->assertTrue( @@ -485,7 +492,7 @@ public function testCanHS256EncodeAValidPayload() $testConfig = $this->signingMinimal; $o = new OAuth2($testConfig); $payload = $o->toJwt(); - $roundTrip = JWT::decode($payload, $testConfig['signingKey'], array('HS256')); + $roundTrip = JWT::decode($payload, new Key($testConfig['signingKey'], 'HS256')); $this->assertEquals($roundTrip->iss, $testConfig['issuer']); $this->assertEquals($roundTrip->aud, $testConfig['audience']); $this->assertEquals($roundTrip->scope, $testConfig['scope']); @@ -500,7 +507,7 @@ public function testCanRS256EncodeAValidPayload() $o->setSigningAlgorithm('RS256'); $o->setSigningKey($privateKey); $payload = $o->toJwt(); - $roundTrip = JWT::decode($payload, $publicKey, array('RS256')); + $roundTrip = JWT::decode($payload, new Key($publicKey, 'RS256')); $this->assertEquals($roundTrip->iss, $testConfig['issuer']); $this->assertEquals($roundTrip->aud, $testConfig['audience']); $this->assertEquals($roundTrip->scope, $testConfig['scope']); @@ -517,7 +524,7 @@ public function testCanHaveAdditionalClaims() $o->setSigningAlgorithm('RS256'); $o->setSigningKey($privateKey); $payload = $o->toJwt(); - $roundTrip = JWT::decode($payload, $publicKey, array('RS256')); + $roundTrip = JWT::decode($payload, new Key($publicKey, 'RS256')); $this->assertEquals($roundTrip->target_audience, $targetAud); } } @@ -907,7 +914,7 @@ public function testFailsIfIdTokenIsInvalid() $not_a_jwt = 'not a jot'; $o = new OAuth2($testConfig); $o->setIdToken($not_a_jwt); - $o->verifyIdToken($this->publicKey); + $o->verifyIdToken($this->publicKey, 'RS256'); } public function testFailsIfAudienceIsMissing() @@ -923,7 +930,7 @@ public function testFailsIfAudienceIsMissing() $o = new OAuth2($testConfig); $jwtIdToken = JWT::encode($origIdToken, $this->privateKey, 'RS256'); $o->setIdToken($jwtIdToken); - $o->verifyIdToken($this->publicKey, ['RS256']); + $o->verifyIdToken($this->publicKey, 'RS256'); } public function testFailsIfAudienceIsWrong() @@ -940,7 +947,7 @@ public function testFailsIfAudienceIsWrong() $o = new OAuth2($testConfig); $jwtIdToken = JWT::encode($origIdToken, $this->privateKey, 'RS256'); $o->setIdToken($jwtIdToken); - $o->verifyIdToken($this->publicKey, ['RS256']); + $o->verifyIdToken($this->publicKey, 'RS256'); } public function testShouldReturnAValidIdToken() @@ -957,7 +964,7 @@ public function testShouldReturnAValidIdToken() $alg = 'RS256'; $jwtIdToken = JWT::encode($origIdToken, $this->privateKey, $alg); $o->setIdToken($jwtIdToken); - $roundTrip = $o->verifyIdToken($this->publicKey, array($alg)); + $roundTrip = $o->verifyIdToken($this->publicKey, $alg); $this->assertEquals($origIdToken['aud'], $roundTrip->aud); } }