add CheckClientCredentials middleware

This commit is contained in:
1elf-me
2021-03-20 16:48:50 +01:00
parent e006cd64b5
commit 7805933b10
5 changed files with 127 additions and 2 deletions

3
.gitignore vendored
View File

@@ -1,3 +1,4 @@
vendor
.phpunit.result.cache
.idea
.idea
composer.lock

View File

@@ -14,7 +14,8 @@
"illuminate/support": "^8.0",
"illuminate/console": "^8.0",
"guzzlehttp/guzzle": "^6.3|^7.0.1",
"socialiteproviders/manager": "^3.4"
"socialiteproviders/manager": "^3.4",
"firebase/php-jwt": "^5.2"
},
"require-dev": {
"phpunit/phpunit": "^8.0",

0
oauth-public.key Normal file
View File

View File

@@ -0,0 +1,41 @@
<?php
namespace GhostZero\BitinflowAccounts\Exceptions;
use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Support\Arr;
class MissingScopeException extends AuthorizationException
{
/**
* The scopes that the user did not have.
*
* @var array
*/
protected $scopes;
/**
* Create a new missing scope exception.
*
* @param array|string $scopes
* @param string $message
*
* @return void
*/
public function __construct($scopes = [], $message = 'Invalid scope(s) provided.')
{
parent::__construct($message);
$this->scopes = Arr::wrap($scopes);
}
/**
* Get the scopes that the user did not have.
*
* @return array
*/
public function scopes()
{
return $this->scopes;
}
}

View File

@@ -0,0 +1,82 @@
<?php
namespace GhostZero\BitinflowAccounts\Http\Middleware;
use Closure;
use Firebase\JWT\JWT;
use Illuminate\Auth\AuthenticationException;
use Illuminate\Http\Request;
use GhostZero\BitinflowAccounts\Exceptions\MissingScopeException;
use stdClass;
use Throwable;
class CheckClientCredentials
{
public const ALLOWED_ALGORITHMS = ['RS256'];
/**
* Handle an incoming request.
*
* @param Request $request
* @param Closure $next
* @param mixed ...$scopes
*
* @throws AuthenticationException|MissingScopeException
*
* @return mixed
*/
public function handle($request, Closure $next, ...$scopes)
{
JWT::$leeway = 60;
try {
$decoded = JWT::decode(
$request->bearerToken(),
$this->getOauthPublicKey(),
self::ALLOWED_ALGORITHMS
);
} catch (Throwable $exception) {
throw new AuthenticationException();
}
$request->attributes->set('oauth_access_token_id', $decoded->jti);
$request->attributes->set('oauth_client_id', $decoded->aud);
$request->attributes->set('oauth_client_trusted', $decoded->client->trusted);
$request->attributes->set('oauth_user_id', $decoded->sub);
$request->attributes->set('oauth_scopes', $decoded->scopes);
$this->validateScopes($decoded, $scopes);
return $next($request);
}
private function getOauthPublicKey()
{
return file_get_contents(__DIR__ . '/../../../../../oauth-public.key');
}
/**
* Validate token credentials.
*
* @param stdClass $token
* @param array $scopes
*
* @throws MissingScopeException
*
* @return void
*/
protected function validateScopes(stdClass $token, array $scopes)
{
if (empty($scopes) || in_array('*', $token->scopes)) {
return;
}
foreach ($scopes as $scope) {
if (in_array($scope, $token->scopes)) {
return;
}
}
throw new MissingScopeException($scopes);
}
}