[ Mini Kiebo ]
Server: Windows NT AKFAR_SERVER 10.0 build 26200 (Windows 10) AMD64
Path:
D:
/
Jurnal PSCP
/
lib
/
pkp
/
classes
/
security
/
authorization
/
internal
/
[
Home
]
File: ApiTokenDecodingMiddleware.inc.php
<?php /** * @file classes/security/authorization/internal/ApiTokenDecodingMiddleware.inc.php * * Copyright (c) 2014-2021 Simon Fraser University * Copyright (c) 2000-2021 John Willinsky * Distributed under the GNU GPL v3. For full terms see the file docs/COPYING. * * @class ApiTokenDecodingMiddleware * @ingroup security_authorization * * @brief Slim middleware which decodes and validates JSON Web Tokens */ use \Firebase\JWT\JWT; use Firebase\JWT\SignatureInvalidException; use Slim\Http\Request as SlimRequest; class ApiTokenDecodingMiddleware { /** @var APIHandler $handler Reference to api handler */ protected $_handler = null; /** * Constructor * * @param APIHandler $handler */ public function __construct(APIHandler $handler) { $this->_handler = $handler; } /** * Decodes the request's JSON Web Token * @param SlimRequest $slimRequest * * @return boolean|string */ protected function _decode($slimRequest) { try { $jwt = $this->getJWT($slimRequest); } catch (Exception $e) { $request = $this->_handler->getRequest(); return $request->getRouter() ->handleAuthorizationFailure( $request, $e->getMessage() ); } if (!$jwt) { /** * If we don't have a token, it's for the authentication logic to handle if it's a problem. */ return true; } $secret = Config::getVar('security', 'api_key_secret', ''); if (!$secret) { $request = $this->_handler->getRequest(); return $request->getRouter() ->handleAuthorizationFailure( $request, 'api.500.apiSecretKeyMissing' ); } try { $apiToken = JWT::decode($jwt, $secret, ['HS256']); /** * Compatibility with old API keys * @link https://github.com/pkp/pkp-lib/issues/6462 */ if (substr($apiToken, 0, 2) === '""') { $apiToken = json_decode($apiToken); } $this->_handler->setApiToken($apiToken); return true; } catch (Exception $e) { /** * If JWT decoding fails, it throws an 'UnexpectedValueException'. * If JSON decoding fails (of the JWT payload), it throws a 'DomainException'. * If token couldn't verified, it throws a 'SignatureInvalidException'. */ if (is_a($e, SignatureInvalidException::class)) { $request = $this->_handler->getRequest(); return $request->getRouter() ->handleAuthorizationFailure( $request, 'api.400.invalidApiToken' ); } if (is_a($e, 'UnexpectedValueException') || is_a($e, 'DomainException') ) { $request = $this->_handler->getRequest(); return $request->getRouter() ->handleAuthorizationFailure( $request, 'api.400.tokenCouldNotBeDecoded', [ 'error' => $e->getMessage() ] ); } throw $e; } // If we do not have a token, it's for the authentication logic // to decide if that's a problem. return true; } /** * Middleware invokable function * * @param SlimRequest $request request * @param SlimResponse $response response * @param callable $next Next middleware * @return boolean|string|unknown */ public function __invoke($request, $response, $next) { $result = $this->_decode($request); if ($result !== true) { return $result; } $response = $next($request, $response); return $response; } protected function getJWT(SlimRequest $slimRequest) { $authHeader = $slimRequest->getHeader('Authorization'); if (!count($authHeader) || empty($authHeader[0])) { return $slimRequest->getQueryParam('apiToken'); } // Several authorization methods may be supplied with commas between them. // For example: Basic basic_auth_string_here, Bearer api_key_here // JWT uses the Bearer scheme with an API key. Ignore the others. $clauses = explode(',', $authHeader[0]); foreach ($clauses as $clause) { // Split the authorization scheme and parameters and look for the Bearer scheme. $parts = explode(' ', trim($clause)); if (count($parts) == 2 && $parts[0] == 'Bearer') { // Found bearer authorization; return the token. return $parts[1]; } } return null; } }