Commit dd6c80b4 authored by Sonia Zorba's avatar Sonia Zorba
Browse files

Handled JWT verification for WS endpoints

parent 719e7463
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -29,7 +29,7 @@ class IdTokenBuilder {
            'iss' => $this->locator->config->jwtIssuer,
            'sub' => $user->id,
            'iat' => time(),
            'exp' => time() + 120,
            'exp' => time() + 3600,
            'name' => $user->getCompleteName()
        );

+29 −1
Original line number Diff line number Diff line
@@ -2,6 +2,8 @@

namespace RAP;

use \Firebase\JWT\JWT;

class OAuth2RequestHandler {

    private $locator;
@@ -166,7 +168,33 @@ class OAuth2RequestHandler {
        }

        $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");
        }
    }
+2 −0
Original line number Diff line number Diff line
@@ -6,6 +6,8 @@ interface JWKSDAO {

    public function getRSAKeyPairs(): array;

    public function getRSAKeyPairById(string $id): ?RSAKeyPair;

    public function insertRSAKeyPair(RSAKeyPair $keyPair): RSAKeyPair;

    public function getNewestKeyPair(): RSAKeyPair;
+17 −0
Original line number Diff line number Diff line
@@ -43,6 +43,23 @@ class MySQLJWKSDAO extends BaseMySQLDAO implements JWKSDAO {
        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 {
        $dbh = $this->getDBHandler();

+2 −0
Original line number Diff line number Diff line
@@ -37,12 +37,14 @@ Flight::map('error', function($ex) {
        http_response_code(401);
        echo "Unauthorized: " . $ex->message;
    } else if ($ex instanceof \Exception) {
        http_response_code(500);
        if ($ex->getMessage() !== null) {
            echo $ex->getMessage();
        } else {
            echo $ex->getTraceAsString();
        }
    } else {
        http_response_code(500);
        throw $ex;
    }
});