Skip to content
Snippets Groups Projects
Commit dd6c80b4 authored by Sonia Zorba's avatar Sonia Zorba
Browse files

Handled JWT verification for WS endpoints

parent 719e7463
No related branches found
No related tags found
No related merge requests found
...@@ -29,7 +29,7 @@ class IdTokenBuilder { ...@@ -29,7 +29,7 @@ class IdTokenBuilder {
'iss' => $this->locator->config->jwtIssuer, 'iss' => $this->locator->config->jwtIssuer,
'sub' => $user->id, 'sub' => $user->id,
'iat' => time(), 'iat' => time(),
'exp' => time() + 120, 'exp' => time() + 3600,
'name' => $user->getCompleteName() 'name' => $user->getCompleteName()
); );
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
namespace RAP; namespace RAP;
use \Firebase\JWT\JWT;
class OAuth2RequestHandler { class OAuth2RequestHandler {
private $locator; private $locator;
...@@ -166,7 +168,33 @@ class OAuth2RequestHandler { ...@@ -166,7 +168,33 @@ class OAuth2RequestHandler {
} }
$accessToken = $this->locator->getAccessTokenDAO()->getAccessToken($bearer_token); $accessToken = $this->locator->getAccessTokenDAO()->getAccessToken($bearer_token);
if ($accessToken->expired) { if ($accessToken === null) {
$this->attemptJWTTokenValidation($bearer_token);
} else if ($accessToken->expired) {
throw new UnauthorizedException("Access token is expired");
}
}
private function attemptJWTTokenValidation($jwt): void {
$jwtParts = explode('.', $jwt);
if (count($jwtParts) === 0) {
throw new UnauthorizedException("Invalid token");
}
$header = JWT::jsonDecode(JWT::urlsafeB64Decode($jwtParts[0]));
if (!isset($header->kid)) {
throw new UnauthorizedException("Invalid token: missing kid in header");
}
$keyPair = $this->locator->getJWKSDAO()->getRSAKeyPairById($header->kid);
if ($keyPair === null) {
throw new UnauthorizedException("Invalid kid: no key found");
}
try {
JWT::decode($jwt, $keyPair->publicKey, [$keyPair->alg]);
} catch (\Firebase\JWT\ExpiredException $ex) {
throw new UnauthorizedException("Access token is expired"); throw new UnauthorizedException("Access token is expired");
} }
} }
......
...@@ -6,6 +6,8 @@ interface JWKSDAO { ...@@ -6,6 +6,8 @@ interface JWKSDAO {
public function getRSAKeyPairs(): array; public function getRSAKeyPairs(): array;
public function getRSAKeyPairById(string $id): ?RSAKeyPair;
public function insertRSAKeyPair(RSAKeyPair $keyPair): RSAKeyPair; public function insertRSAKeyPair(RSAKeyPair $keyPair): RSAKeyPair;
public function getNewestKeyPair(): RSAKeyPair; public function getNewestKeyPair(): RSAKeyPair;
......
...@@ -43,6 +43,23 @@ class MySQLJWKSDAO extends BaseMySQLDAO implements JWKSDAO { ...@@ -43,6 +43,23 @@ class MySQLJWKSDAO extends BaseMySQLDAO implements JWKSDAO {
return $keyPairs; return $keyPairs;
} }
public function getRSAKeyPairById(string $id): ?RSAKeyPair {
$dbh = $this->getDBHandler();
$query = "SELECT id, private_key, public_key, alg, creation_time FROM rsa_keypairs WHERE id = :id";
$stmt = $dbh->prepare($query);
$stmt->bindParam(':id', $id);
$stmt->execute();
foreach ($stmt->fetchAll() as $row) {
return $this->getRSAKeyPairFromResultRow($row);
}
return null;
}
public function getNewestKeyPair(): RSAKeyPair { public function getNewestKeyPair(): RSAKeyPair {
$dbh = $this->getDBHandler(); $dbh = $this->getDBHandler();
......
...@@ -37,12 +37,14 @@ Flight::map('error', function($ex) { ...@@ -37,12 +37,14 @@ Flight::map('error', function($ex) {
http_response_code(401); http_response_code(401);
echo "Unauthorized: " . $ex->message; echo "Unauthorized: " . $ex->message;
} else if ($ex instanceof \Exception) { } else if ($ex instanceof \Exception) {
http_response_code(500);
if ($ex->getMessage() !== null) { if ($ex->getMessage() !== null) {
echo $ex->getMessage(); echo $ex->getMessage();
} else { } else {
echo $ex->getTraceAsString(); echo $ex->getTraceAsString();
} }
} else { } else {
http_response_code(500);
throw $ex; throw $ex;
} }
}); });
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment