Skip to content

Commit

Permalink
add CheckClientCredentials middleware
Browse files Browse the repository at this point in the history
  • Loading branch information
1elf-me committed Mar 20, 2021
1 parent e006cd6 commit 7805933
Show file tree
Hide file tree
Showing 5 changed files with 127 additions and 2 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
vendor
.phpunit.result.cache
.idea
.idea
composer.lock
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
Empty file added oauth-public.key
Empty file.
Original file line number Diff line number Diff line change
@@ -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;
}
}
Original file line number Diff line number Diff line change
@@ -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);
}
}

0 comments on commit 7805933

Please sign in to comment.