Skip to content

Commit

Permalink
Updates to JWT handling
Browse files Browse the repository at this point in the history
  • Loading branch information
spvickers committed Sep 25, 2020
1 parent cc86068 commit 4df03d4
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 62 deletions.
4 changes: 1 addition & 3 deletions src/AccessToken.php
Original file line number Diff line number Diff line change
Expand Up @@ -168,9 +168,7 @@ public function get($scope = '', $scopeOnly = false)
'scope' => implode(' ', $scopesRequested)
);
if (!empty(Tool::$defaultTool)) {
if (empty(Tool::$defaultTool->platform)) {
Tool::$defaultTool->platform = $this->platform;
}
Tool::$defaultTool->platform = $this->platform;
$body = Tool::$defaultTool->signServiceRequest($url, $method, $type, $body);
} else {
$body = $this->platform->signServiceRequest($url, $method, $type, $body);
Expand Down
32 changes: 23 additions & 9 deletions src/Jwt/WebTokenClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,19 +58,30 @@ public function isEncrypted()
*/
public function load($jwtString, $privateKey = null)
{
$ok = true;
$this->jwe = null;
$this->jwt = null;
$this->claims = null;
try {
$serializer = new Signature\Serializer\CompactSerializer();
$this->jwt = $serializer->unserialize($jwtString);
} catch (\Exception $e) {
$serializer = new Encryption\Serializer\CompactSerializer();
$this->jwt = $serializer->unserialize($jwtString);
$ok = false;
}
if (!$ok) {
try {
$serializer = new Encryption\Serializer\CompactSerializer();
$this->jwt = $serializer->unserialize($jwtString);
$ok = $this->decrypt($privateKey);
} catch (\Exception $e) {
$ok = false;
}
}
if ($this->decrypt($privateKey)) {
if ($ok) {
$this->claims = json_decode($this->jwt->getPayload(), true);
}

return $ok;
}

/**
Expand Down Expand Up @@ -430,7 +441,7 @@ public static function getJWKS($pemKey, $signatureMethod, $kid)
*/
private function decrypt($privateKey)
{
$ok = true;
$ok = false;
if ($this->jwt instanceof Encryption\JWE) {
$this->jwe = clone $this->jwt;
$keyEnc = $this->jwe->getSharedProtectedHeaderParameter('alg');
Expand All @@ -447,11 +458,14 @@ private function decrypt($privateKey)
$jweDecrypter = new Encryption\JWEDecrypter($keyEncryptionAlgorithmManager, $contentEncryptionAlgorithmManager,
$compressionMethodManager);
if ($jweDecrypter->decryptUsingKey($this->jwt, $jwk, 0)) {
$jwt = $this->jwt->getPayload();
$serializer = new Signature\Serializer\CompactSerializer();
$this->jwt = $serializer->unserialize($jwt);
} else {
$ok = false;
try {
$jwt = $this->jwt->getPayload();
$serializer = new Signature\Serializer\CompactSerializer();
$this->jwt = $serializer->unserialize($jwt);
$ok = true;
} catch (\Exception $e) {
$ok = false;
}
}
}

Expand Down
104 changes: 54 additions & 50 deletions src/System.php
Original file line number Diff line number Diff line change
Expand Up @@ -529,69 +529,73 @@ private function parseMessage()
try {
$this->jwt = Jwt::getJwtClient();
if (isset($this->rawParameters['id_token'])) {
$this->jwt->load($this->rawParameters['id_token'], $this->rsaKey);
$this->ok = $this->jwt->load($this->rawParameters['id_token'], $this->rsaKey);
} else {
$this->jwt->load($this->rawParameters['JWT'], $this->rsaKey);
$this->ok = $this->jwt->load($this->rawParameters['JWT'], $this->rsaKey);
}
$this->ok = $this->jwt->hasClaim('iss') && $this->jwt->hasClaim('aud') &&
$this->jwt->hasClaim(Util::JWT_CLAIM_PREFIX . '/claim/deployment_id');
if ($this->ok) {
$iss = $this->jwt->getClaim('iss');
$aud = $this->jwt->getClaim('aud');
$deploymentId = $this->jwt->getClaim(Util::JWT_CLAIM_PREFIX . '/claim/deployment_id');
$this->ok = !empty($iss) && !empty($aud) && !empty($deploymentId);
if (!$this->ok) {
$this->reason = 'iss, aud and/or deployment_id claim is empty';
} elseif (is_array($aud)) {
if ($this->jwt->hasClaim('azp')) {
$this->ok = !empty($this->jwt->getClaim('azp'));
if (!$this->ok) {
$this->reason = 'azp claim is empty';
} else {
$this->ok = in_array($this->jwt->getClaim('azp'), $aud);
if ($this->ok) {
$aud = $this->jwt->getClaim('azp');
if (!$this->ok) {
$this->reason = 'Message does not contain a valid JWT';
} else {
$this->ok = $this->jwt->hasClaim('iss') && $this->jwt->hasClaim('aud') &&
$this->jwt->hasClaim(Util::JWT_CLAIM_PREFIX . '/claim/deployment_id');
if ($this->ok) {
$iss = $this->jwt->getClaim('iss');
$aud = $this->jwt->getClaim('aud');
$deploymentId = $this->jwt->getClaim(Util::JWT_CLAIM_PREFIX . '/claim/deployment_id');
$this->ok = !empty($iss) && !empty($aud) && !empty($deploymentId);
if (!$this->ok) {
$this->reason = 'iss, aud and/or deployment_id claim is empty';
} elseif (is_array($aud)) {
if ($this->jwt->hasClaim('azp')) {
$this->ok = !empty($this->jwt->getClaim('azp'));
if (!$this->ok) {
$this->reason = 'azp claim is empty';
} else {
$this->reason = 'azp claim value is not included in aud claim';
$this->ok = in_array($this->jwt->getClaim('azp'), $aud);
if ($this->ok) {
$aud = $this->jwt->getClaim('azp');
} else {
$this->reason = 'azp claim value is not included in aud claim';
}
}
} else {
$aud = $aud[0];
$this->ok = !empty($aud);
if (!$this->ok) {
$this->reason = 'First element of aud claim is empty';
}
}
} else {
$aud = $aud[0];
$this->ok = !empty($aud);
} elseif ($this->jwt->hasClaim('azp')) {
$this->ok = $this->jwt->getClaim('azp') === $aud;
if (!$this->ok) {
$this->reason = 'First element of aud claim is empty';
$this->reason = 'aud claim does not match the azp claim';
}
}
} elseif ($this->jwt->hasClaim('azp')) {
$this->ok = $this->jwt->getClaim('azp') === $aud;
if (!$this->ok) {
$this->reason = 'aud claim does not match the azp claim';
}
}
if ($this->ok) {
$this->platform = Platform::fromPlatformId($iss, $aud, $deploymentId, $this->dataConnector);
if (isset($this->rawParameters['id_token'])) {
$this->ok = !empty($this->rawParameters['state']);
if ($this->ok) {
$nonce = new PlatformNonce($this->platform, $this->rawParameters['state']);
$this->ok = $nonce->load();
if ($this->ok) {
$this->platform = Platform::fromPlatformId($iss, $aud, $deploymentId, $this->dataConnector);
if (isset($this->rawParameters['id_token'])) {
$this->ok = !empty($this->rawParameters['state']);
if ($this->ok) {
$this->ok = $nonce->delete();
$nonce = new PlatformNonce($this->platform, $this->rawParameters['state']);
$this->ok = $nonce->load();
if ($this->ok) {
$this->ok = $nonce->delete();
}
}
}
if ($this->ok) {
$this->platform->platformId = $this->jwt->getClaim('iss');
$this->messageParameters = array();
$this->messageParameters['oauth_consumer_key'] = $aud;
$this->messageParameters['oauth_signature_method'] = $this->jwt->getHeader('alg');
$this->parseClaims();
} else {
$this->reason = 'state parameter is invalid or missing';
}
}
if ($this->ok) {
$this->platform->platformId = $this->jwt->getClaim('iss');
$this->messageParameters = array();
$this->messageParameters['oauth_consumer_key'] = $aud;
$this->messageParameters['oauth_signature_method'] = $this->jwt->getHeader('alg');
$this->parseClaims();
} else {
$this->reason = 'state parameter is invalid or missing';
}
} else {
$this->reason = 'iss, aud and/or deployment_id claim not found';
}
} else {
$this->reason = 'iss, aud and/or deployment_id claim not found';
}
} catch (\Exception $e) {
$this->ok = false;
Expand Down

0 comments on commit 4df03d4

Please sign in to comment.