diff --git a/composer.json b/composer.json index b00db20..7a95277 100755 --- a/composer.json +++ b/composer.json @@ -12,7 +12,8 @@ "require": { "php": "^7.0", "guzzlehttp/guzzle": "~6.0", - "laravel/framework": "^5.5" + "laravel/framework": "^5.5", + "laravel/passport": "^4.0" }, "autoload": { "psr-4": {"DesignMyNight\\Laravel\\OAuth2\\": "src/"} diff --git a/src/Exceptions/InvalidAccessTokenException.php b/src/Exceptions/InvalidAccessTokenException.php deleted file mode 100644 index 9973f89..0000000 --- a/src/Exceptions/InvalidAccessTokenException.php +++ /dev/null @@ -1,6 +0,0 @@ -<?php -namespace DesignMyNight\Laravel\OAuth2\Exceptions; - -class InvalidAccessTokenException extends \Exception -{ -} diff --git a/src/Exceptions/InvalidEndpointException.php b/src/Exceptions/InvalidEndpointException.php deleted file mode 100644 index d15cd7e..0000000 --- a/src/Exceptions/InvalidEndpointException.php +++ /dev/null @@ -1,6 +0,0 @@ -<?php -namespace DesignMyNight\Laravel\OAuth2\Exceptions; - -class InvalidEndpointException extends InvalidAccessTokenException -{ -} diff --git a/src/Exceptions/InvalidInputException.php b/src/Exceptions/InvalidInputException.php deleted file mode 100644 index 4eaaaec..0000000 --- a/src/Exceptions/InvalidInputException.php +++ /dev/null @@ -1,6 +0,0 @@ -<?php -namespace DesignMyNight\Laravel\OAuth2\Exceptions; - -class InvalidInputException extends InvalidAccessTokenException -{ -} diff --git a/src/VerifyAccessToken.php b/src/VerifyAccessToken.php index 7c2389a..5b7671b 100755 --- a/src/VerifyAccessToken.php +++ b/src/VerifyAccessToken.php @@ -2,12 +2,11 @@ namespace DesignMyNight\Laravel\OAuth2; use Closure; -use DesignMyNight\Laravel\OAuth2\Exceptions\InvalidAccessTokenException; -use DesignMyNight\Laravel\OAuth2\Exceptions\InvalidEndpointException; -use DesignMyNight\Laravel\OAuth2\Exceptions\InvalidInputException; use GuzzleHttp\Client; use GuzzleHttp\Exception\RequestException; +use Illuminate\Auth\AuthenticationException; use Illuminate\Support\Facades\Cache; +use Laravel\Passport\Exceptions\MissingScopeException; class VerifyAccessToken { @@ -15,20 +14,33 @@ class VerifyAccessToken private $client = null; - private function getClient(): Client + protected function checkScopes($scopesForToken, $requiredScopes) { - if ($this->client === null) { - $this->setClient(new Client()); + if (!is_array($requiredScopes)) { + $requiredScopes = [$requiredScopes]; } - return $this->client; + $misingScopes = array_diff($scopesForToken, $scopesForToken); + + if (count($misingScopes) > 0) { + throw new MissingScopeException($misingScopes); + } } - public function setClient(Client $client): self + protected function getAccessToken(): string { - $this->client = $client; + $accessToken = Cache::get($this->accessTokenCacheKey); - return $this; + return $accessToken ?: $this->getNewAccessToken(); + } + + private function getClient(): Client + { + if ($this->client === null) { + $this->setClient(new Client()); + } + + return $this->client; } protected function getIntrospect($accessToken) @@ -46,37 +58,6 @@ protected function getIntrospect($accessToken) return json_decode((string) $response->getBody(), true); } - protected function getAccessToken(): string - { - $accessToken = Cache::get($this->accessTokenCacheKey); - - return $accessToken ?: $this->getNewAccessToken(); - } - - protected function getNewAccessToken(): string - { - $response = $this->getClient()->post(config('authorizationserver.token_url'), [ - 'form_params' => [ - 'grant_type' => 'client_credentials', - 'client_id' => config('authorizationserver.client_id'), - 'client_secret' => config('authorizationserver.client_secret'), - 'scope' => '', - ], - ]); - - $result = json_decode((string) $response->getBody(), true); - - if (isset($result['access_token'])) { - $accessToken = $result['access_token']; - - Cache::add($this->accessTokenCacheKey, $accessToken, intVal($result['expires_in']) / 60); - - return $accessToken; - } - - throw new InvalidEndpointException('Did not receive an access token'); - } - /** * Handle an incoming request. * @@ -86,50 +67,65 @@ protected function getNewAccessToken(): string */ public function handle($request, Closure $next, ...$scopes) { - $authorization = $request->header('Authorization'); - - if (!$authorization) { - throw new InvalidInputException('No Authorization header present'); - } - $bearerToken = $request->bearerToken(); if (!$bearerToken) { - throw new InvalidInputException('No Bearer token in the Authorization header present'); + throw new AuthenticationException('No Bearer token present'); } try { $result = $this->getIntrospect($bearerToken); if (!$result['active']) { - throw new InvalidAccessTokenException('Invalid token!'); + throw new AuthenticationException('Invalid token!'); } - if ($scopes != null) { - if (!\is_array($scopes)) { - $scopes = [$scopes]; - } - - $scopesForToken = \explode(' ', $result['scope']); - - if (count($misingScopes = array_diff($scopes, $scopesForToken)) > 0) { - throw new InvalidAccessTokenException('Missing the following required scopes: ' . implode(' ,', $misingScopes)); - } + if ($scopes !== null) { + $this->checkScopes(explode(' ', $result['scope']), $scopes); } } catch (RequestException $e) { if ($e->hasResponse()) { $result = json_decode((string) $e->getResponse()->getBody(), true); if (isset($result['error'])) { - throw new InvalidAccessTokenException($result['error']['title'] ?? 'Invalid token!'); + throw new AuthenticationException($result['error']['title'] ?? ''); } - - throw new InvalidAccessTokenException('Invalid token!'); } - throw new InvalidAccessTokenException($e); + throw new AuthenticationException($e->getMessage()); } return $next($request); } + + protected function getNewAccessToken(): string + { + $response = $this->getClient()->post(config('authorizationserver.token_url'), [ + 'form_params' => [ + 'grant_type' => 'client_credentials', + 'client_id' => config('authorizationserver.client_id'), + 'client_secret' => config('authorizationserver.client_secret'), + 'scope' => '', + ], + ]); + + $result = json_decode((string) $response->getBody(), true); + + if (isset($result['access_token'])) { + $accessToken = $result['access_token']; + + Cache::add($this->accessTokenCacheKey, $accessToken, intVal($result['expires_in']) / 60); + + return $accessToken; + } + + throw new AuthenticationException('Did not receive an access token'); + } + + public function setClient(Client $client): self + { + $this->client = $client; + + return $this; + } }