Skip to content
Snippets Groups Projects
Select Git revision
  • 46229f4e4a7e5c2c988218bb9df6c5c3b89988a6
  • master default
  • rocky-linux-9
  • development
  • v1.0.4
  • v1.0.3
  • v1.0.2
7 results

TokenChecker.php

Blame
  • TokenChecker.php 2.22 KiB
    <?php
    
    namespace RAP;
    
    use \Firebase\JWT\JWT;
    
    class TokenChecker {
    
        private $locator;
    
        public function __construct(Locator $locator) {
            $this->locator = $locator;
        }
    
        public function validateToken(): object {
            $headers = apache_request_headers();
    
            if (!isset($headers['Authorization'])) {
                throw new BadRequestException("Missing Authorization header");
            }
    
            $authorizationHeader = explode(" ", $headers['Authorization']);
            if ($authorizationHeader[0] === "Bearer") {
                $token = $authorizationHeader[1];
            } else {
                throw new BadRequestException("Invalid token type");
            }
    
            return $this->getValidTokenObject($token);
        }
    
        public function getValidTokenObject(string $jwt): object {
    
            $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 {
                $token = JWT::decode($jwt, $keyPair->publicKey, [$keyPair->alg]);
    
                if (!isset($token->sub)) {
                    throw new UnauthorizedException("Invalid token: missing subject claim");
                }
    
                return $token;
            } catch (\Firebase\JWT\ExpiredException $ex) {
                throw new UnauthorizedException("Access token is expired");
            }
        }
    
        public function checkScope(object $tokenData, string $desiredScope): void {
    
            if (!(isset($tokenData->scope))) {
                throw new UnauthorizedException("Missing 'scope' claim in access token");
            }
    
            $scopes = explode(' ', $tokenData->scope);
    
            foreach ($scopes as $scope) {
                if ($scope === $desiredScope) {
                    return;
                }
            }
    
            throw new UnauthorizedException("Scope '$desiredScope' is required for performing this action");
        }
    
    }