31 private $jwtString =
null;
38 private $jwtHeaders =
null;
45 private $jwtPayload =
null;
52 private static $lastHeaders =
null;
59 private static $lastPayload =
null;
78 return !empty($this->jwtString);
99 public function load($jwtString, $privateKey =
null)
101 $sections = explode(
'.', $jwtString);
102 $ok = count($sections) === 3;
106 $ok = !is_null($headers) && !is_null($payload);
109 $this->jwtString = $jwtString;
110 $this->jwtHeaders = $headers;
111 $this->jwtPayload = $payload;
113 $this->jwtString =
null;
114 $this->jwtHeaders =
null;
115 $this->jwtPayload =
null;
140 return !empty($this->jwtHeaders) && isset($this->jwtHeaders->{$name});
153 if ($this->hasHeader($name)) {
154 $value = $this->jwtHeaders->{$name};
156 $value = $defaultValue;
169 return $this->jwtHeaders;
179 return self::$lastHeaders;
191 return !empty($this->jwtPayload) && isset($this->jwtPayload->{$name});
202 public function getClaim($name, $defaultValue =
null)
204 if ($this->hasClaim($name)) {
205 $value = $this->jwtPayload->{$name};
207 $value = $defaultValue;
220 return $this->jwtPayload;
230 return self::$lastPayload;
241 public function verify($publicKey, $jku =
null)
244 $hasPublicKey = !empty($publicKey);
246 if (is_string($publicKey)) {
247 $json = Util::jsonDecode($publicKey,
true);
248 if (!is_null($json)) {
250 $jwks = array(
'keys' => array($json));
251 $publicKey = static::parseKeySet($jwks);
252 }
catch (\Exception $e) {
256 $publicKey =
new Key($publicKey, $this->getHeader(
'alg'));
259 } elseif (!empty($jku)) {
260 $publicKey = $this->fetchPublicKey($jku);
262 JWT::$leeway = Jwt::$leeway;
266 JWT::decode($this->jwtString, $publicKey);
268 }
catch (\Exception $e) {
269 Util::logError($e->getMessage());
272 } elseif ($hasPublicKey && !empty($jku)) {
274 $publicKey = $this->fetchPublicKey($jku);
276 }
catch (\Exception $e) {
281 }
while (!$ok && $retry);
300 public static function sign($payload, $signatureMethod, $privateKey, $kid =
null, $jku =
null, $encryptionMethod =
null,
303 if (!empty($encryptionMethod)) {
304 $errorMessage =
'Encrypted tokens not supported by the Firebase JWT client';
305 Util::logError($errorMessage);
306 throw new \Exception($errorMessage);
308 $jwtString = JWT::encode($payload, $privateKey, $signatureMethod, $kid);
309 $sections = explode(
'.', $jwtString);
310 self::$lastHeaders = Util::jsonDecode(JWT::urlsafeB64Decode($sections[0]));
311 self::$lastPayload = Util::jsonDecode(JWT::urlsafeB64Decode($sections[1]));
326 switch ($signatureMethod) {
338 "private_key_bits" => $size,
339 "private_key_type" => OPENSSL_KEYTYPE_RSA
341 $res = openssl_pkey_new($config);
342 if ($res !==
false) {
343 if (openssl_pkey_export($res, $privateKey)) {
344 $privateKey = str_replace(
'-----BEGIN PRIVATE KEY-----',
'-----BEGIN RSA PRIVATE KEY-----', $privateKey);
345 $privateKey = str_replace(
'-----END PRIVATE KEY-----',
'-----END RSA PRIVATE KEY-----', $privateKey);
362 $res = openssl_pkey_get_private($privateKey);
363 if ($res !==
false) {
364 $details = openssl_pkey_get_details($res);
365 $publicKey = $details[
'key'];
380 public static function getJWKS($pemKey, $signatureMethod, $kid =
null)
382 $keys[
'keys'] = array();
383 $res = openssl_pkey_get_private($pemKey);
384 if ($res ===
false) {
385 $res = openssl_pkey_get_public($pemKey);
387 if ($res !==
false) {
388 $details = openssl_pkey_get_details($res);
391 'n' => JWT::urlsafeB64Encode($details[
'rsa'][
'n']),
392 'e' => JWT::urlsafeB64Encode($details[
'rsa'][
'e']),
393 'alg' => $signatureMethod,
399 $keys[
'keys'][] = $key;
416 private function fetchPublicKey($jku)
418 $publicKey = array();
421 $keys = Util::jsonDecode($http->response,
true);
422 if (is_array($keys)) {
424 $publicKey = static::parseKeySet($keys);
425 }
catch (\Exception $e) {
448 private static function parseKeySet($jwks)
452 if (!isset($jwks[
'keys'])) {
453 throw new \UnexpectedValueException(
'"keys" member must exist in the JWK Set');
455 if (empty($jwks[
'keys'])) {
456 throw new \InvalidArgumentException(
'JWK Set did not contain any keys');
459 foreach ($jwks[
'keys'] as $k => $v) {
460 if (!empty($v[
'alg'])) {
461 $kid = isset($v[
'kid']) ? $v[
'kid'] : $k;
462 if ($key = JWK::parseKey($v)) {
463 if (!$key instanceof Key) {
464 $key =
new Key($key, $v[
'alg']);
472 throw new \UnexpectedValueException(
'No supported algorithms found in JWK Set');
Class to represent an HTTP message request.
Class to implement the JWT interface using the Firebase JWT library from https://github....
static getLastHeaders()
Get the value of the headers for the last signed JWT (before any encryption).
static getLastPayload()
Get the value of the payload for the last signed JWT (before any encryption).
getHeaders()
Get the value of the headers.
hasJwt()
Check if a JWT is defined.
getJweHeaders()
Get the value of the JWE headers.
static getPublicKey($privateKey)
Get the public key for a private key.
load($jwtString, $privateKey=null)
Load a JWT from a string.
static getJWKS($pemKey, $signatureMethod, $kid=null)
Get the public JWKS from a key in PEM format.
static generateKey($signatureMethod='RS256')
Generate a new private key in PEM format.
const SUPPORTED_ALGORITHMS
Supported signature algorithms.
isEncrypted()
Check if a JWT's content is encrypted.
static getSupportedAlgorithms()
Return an array of supported signature algorithms.
getHeader($name, $defaultValue=null)
Get the value of the header with the specified name.
getClaim($name, $defaultValue=null)
Get the value of the claim with the specified name.
static sign($payload, $signatureMethod, $privateKey, $kid=null, $jku=null, $encryptionMethod=null, $publicKey=null)
Sign the JWT.
hasHeader($name)
Check whether a JWT has a header with the specified name.
getPayload()
Get the value of the payload.
hasClaim($name)
Check whether a JWT has a claim with the specified name.
verify($publicKey, $jku=null)
Verify the signature of the JWT.
Class to represent an HTTP message request.
Class to implement utility methods.
static jsonDecode($str, $associative=false)
Decode a JSON string.
Interface to represent an HWT client.