jwsLoader = $jwsLoaderFactory->create(['jws_compact'], $signatureAlgorithms, $jwsHeaderChecker); if ($jweLoaderFactory !== null && $keyEncryptionAlgorithms !== null && $contentEncryptionAlgorithms !== null && $jweHeaderChecker !== null) { $this->jweLoader = $jweLoaderFactory->create(['jwe_compact'], array_merge($keyEncryptionAlgorithms, $contentEncryptionAlgorithms), null, null, $jweHeaderChecker); $this->continueOnDecryptionFailure = $continueOnDecryptionFailure; } $this->signatureKeyset = JWKSet::createFromJson($signatureKeyset); $this->encryptionKeyset = $encryptionKeyset ? JWKSet::createFromJson($encryptionKeyset) : null; $this->claimCheckerManager = $claimCheckerManagerFactory->create($claimChecker); $this->mandatoryClaims = $mandatoryClaims; } public function load(string $token): array { $token = $this->loadJWE($token); $data = $this->loadJWS($token); try { $this->claimCheckerManager->check($data, $this->mandatoryClaims); } catch (MissingMandatoryClaimException|InvalidClaimException $e) { throw new JWTDecodeFailureException(JWTDecodeFailureException::INVALID_TOKEN, $e->getMessage(), $e, $data); } catch (\Throwable $e) { throw new JWTDecodeFailureException(JWTDecodeFailureException::INVALID_TOKEN, 'Unable to load the token', $e, $data); } return $data; } /** * @return array */ private function loadJWS(string $token): array { $payload = null; $data = null; $signature = null; try { $jws = $this->jwsLoader->loadAndVerifyWithKeySet($token, $this->signatureKeyset, $signature); } catch (\Throwable $e) { throw new JWTDecodeFailureException(JWTDecodeFailureException::INVALID_TOKEN, 'Invalid token. The token cannot be loaded or the signature cannot be verified.'); } if ($signature !== 0) { throw new JWTDecodeFailureException(JWTDecodeFailureException::INVALID_TOKEN, 'Invalid token. The token shall contain only one signature.'); } $payload = $jws->getPayload(); if (!$payload) { throw new JWTDecodeFailureException(JWTDecodeFailureException::INVALID_TOKEN, 'Invalid payload. The token shall contain claims.'); } $data = json_decode($payload, true); if (!is_array($data)) { throw new JWTDecodeFailureException(JWTDecodeFailureException::INVALID_TOKEN, 'Invalid payload. The token shall contain claims.'); } return $data; } private function loadJWE(string $token): string { if (!$this->jweLoader) { return $token; } $recipient = null; try { $jwe = $this->jweLoader->loadAndDecryptWithKeySet($token, $this->encryptionKeyset, $recipient); } catch (\Throwable $e) { if ($this->continueOnDecryptionFailure === true) { return $token; } throw new JWTDecodeFailureException(JWTDecodeFailureException::INVALID_TOKEN, 'Invalid token. The token cannot be decrypted.', $e); } $token = $jwe->getPayload(); if (!$token || $recipient !== 0) { throw new JWTDecodeFailureException(JWTDecodeFailureException::INVALID_TOKEN, 'Invalid token. The token has no valid content.'); } return $token; } }