-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Add introspection implementation #925
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
StevePorter92
wants to merge
31
commits into
thephpleague:master
Choose a base branch
from
StevePorter92:feature/add-introspection-implementation-code-review
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 19 commits
Commits
Show all changes
31 commits
Select commit
Hold shift + click to select a range
9446f0e
Add introspection implementation
fetzi 1ad5514
Apply styleci fixes
fetzi 651ee9b
Apply styleci fixes
fetzi 225553f
Fix phpstan errors
fetzi 880b4bd
Apply styleci fixes
fetzi 487241b
Refactor introspection response to not use exceptions to control the …
eba79d7
refactor response to be more inline with other package reponses
fece711
Merge branch 'master' of github.com:steveporter92/oauth2-server into …
caf15b9
update code style
d143c46
update code style
f00b07e
fix type hints for tests
595cace
fix code style and unit tests and rename introspection params function
33eef79
add validate request method
e4b49c6
add test for extra params
baa74fb
code style fixes
8bf9c36
code style for test
4af0d2a
add more introspection tests
b00e6fa
add introspect example
4805243
remove blank linbe
5eeb624
add missing brackets to new class
b0e6eff
update phpdoc to reflect the function
7def7a8
add missing doc
99cb04a
fix return type
9175628
add missing full stop
d088a3f
create bearer token validator
1737752
add bearer token introspection response
af2cde2
add introspection validator interface
2a1a8b9
refactor introspection response
4611bed
update introspector to use introspection validator interface
2745059
fix code style
66f9843
update phpdoc
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
<?php | ||
|
||
use League\OAuth2\Server\AuthorizationServer; | ||
use League\OAuth2\Server\Exception\OAuthServerException; | ||
use OAuth2ServerExamples\Repositories\AccessTokenRepository; | ||
use OAuth2ServerExamples\Repositories\ClientRepository; | ||
use OAuth2ServerExamples\Repositories\ScopeRepository; | ||
use Psr\Http\Message\ResponseInterface; | ||
use Psr\Http\Message\ServerRequestInterface; | ||
use Slim\App; | ||
|
||
include __DIR__ . '/../vendor/autoload.php'; | ||
|
||
$app = new App([ | ||
// Add the authorization server to the DI container | ||
AuthorizationServer::class => function () { | ||
|
||
// Setup the authorization server | ||
$server = new AuthorizationServer( | ||
new ClientRepository(), // instance of ClientRepositoryInterface | ||
new AccessTokenRepository(), // instance of AccessTokenRepositoryInterface | ||
new ScopeRepository(), // instance of ScopeRepositoryInterface | ||
'file://' . __DIR__ . '/../private.key', // path to private key | ||
'lxZFUEsBCJ2Yb14IF2ygAHI5N4+ZAUXXaSeeJm6+twsUmIen' // encryption key | ||
); | ||
|
||
return $server; | ||
}, | ||
]); | ||
|
||
$app->post( | ||
'/introspect', | ||
function (ServerRequestInterface $request, ResponseInterface $response) use ($app) { | ||
|
||
/* @var \League\OAuth2\Server\AuthorizationServer $server */ | ||
$server = $app->getContainer()->get(AuthorizationServer::class); | ||
|
||
try { | ||
// Validate the given introspect request | ||
$server->validateIntrospectionRequest($request); | ||
|
||
// Try to respond to the introspection request | ||
return $server->respondToIntrospectionRequest($request, $response); | ||
} catch (OAuthServerException $exception) { | ||
|
||
// All instances of OAuthServerException can be converted to a PSR-7 response | ||
return $exception->generateHttpResponse($response); | ||
} catch (\Exception $exception) { | ||
|
||
// Catch unexpected exceptions | ||
$body = $response->getBody(); | ||
$body->write($exception->getMessage()); | ||
|
||
return $response->withStatus(500)->withBody($body); | ||
} | ||
} | ||
); | ||
|
||
$app->run(); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,153 @@ | ||
<?php | ||
|
||
namespace League\OAuth2\Server; | ||
|
||
use InvalidArgumentException; | ||
use Lcobucci\JWT\Parser; | ||
use Lcobucci\JWT\Signer\Keychain; | ||
use Lcobucci\JWT\Signer\Rsa\Sha256; | ||
use Lcobucci\JWT\Token; | ||
use Lcobucci\JWT\ValidationData; | ||
use League\OAuth2\Server\Exception\OAuthServerException; | ||
use League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface; | ||
use League\OAuth2\Server\ResponseTypes\IntrospectionResponse; | ||
use Psr\Http\Message\ServerRequestInterface; | ||
|
||
class Introspector | ||
{ | ||
/** | ||
* @var AccessTokenRepositoryInterface | ||
*/ | ||
private $accessTokenRepository; | ||
|
||
/** | ||
* @var CryptKey | ||
*/ | ||
private $privateKey; | ||
|
||
/** | ||
* @var Parser | ||
*/ | ||
private $parser; | ||
|
||
/** | ||
* New Introspector instance. | ||
* | ||
* @param AccessTokenRepositoryInterface $accessTokenRepository | ||
* @param CryptKey $privateKey | ||
* @param Parser $parser | ||
*/ | ||
public function __construct( | ||
AccessTokenRepositoryInterface $accessTokenRepository, | ||
CryptKey $privateKey, | ||
Parser $parser | ||
) { | ||
$this->accessTokenRepository = $accessTokenRepository; | ||
$this->privateKey = $privateKey; | ||
$this->parser = $parser; | ||
} | ||
|
||
/** | ||
* Validate the request | ||
* | ||
* @param ServerRequestInterface $request | ||
* | ||
* @throws OAuthServerException | ||
*/ | ||
public function validateIntrospectionRequest(ServerRequestInterface $request) | ||
{ | ||
if ($request->getMethod() !== 'POST') { | ||
throw OAuthServerException::accessDenied('Invalid request method'); | ||
} | ||
} | ||
|
||
/** | ||
* Return an introspection response. | ||
* | ||
* @param ServerRequestInterface $request | ||
* @param IntrospectionResponse $responseType | ||
* | ||
* @return IntrospectionResponse | ||
*/ | ||
public function respondToIntrospectionRequest( | ||
ServerRequestInterface $request, | ||
IntrospectionResponse $responseType | ||
) { | ||
$jwt = $request->getParsedBody()['token'] ?? null; | ||
|
||
try { | ||
$token = $this->parser->parse($jwt); | ||
} catch (InvalidArgumentException $e) { | ||
return $responseType; | ||
} | ||
|
||
return $this->isTokenValid($token) ? | ||
$this->setTokenOnResponse($token, $responseType) : | ||
$responseType; | ||
} | ||
|
||
/** | ||
* Validate the JWT and make sure it has not expired or been revoked | ||
* | ||
* @return bool | ||
*/ | ||
private function isTokenValid(Token $token) | ||
{ | ||
return $this->verifyToken($token) && !$this->isTokenExpired($token) && !$this->isTokenRevoked($token); | ||
} | ||
|
||
/** | ||
* Validate the JWT token. | ||
* | ||
* @param Token $token | ||
* | ||
* @return bool | ||
*/ | ||
private function verifyToken(Token $token) | ||
{ | ||
$keychain = new Keychain(); | ||
$key = $keychain->getPrivateKey($this->privateKey->getKeyPath(), $this->privateKey->getPassPhrase()); | ||
|
||
return $token->verify(new Sha256, $key->getContent()); | ||
} | ||
|
||
/** | ||
* Ensure access token hasn't expired | ||
* | ||
* @param Token $token | ||
* | ||
* @return bool | ||
*/ | ||
private function isTokenExpired(Token $token) | ||
{ | ||
$data = new ValidationData(time()); | ||
|
||
return !$token->validate($data); | ||
} | ||
|
||
/** | ||
* Check if the given access token is revoked. | ||
* | ||
* @param Token $token | ||
* | ||
* @return bool | ||
*/ | ||
private function isTokenRevoked(Token $token) | ||
{ | ||
return $this->accessTokenRepository->isAccessTokenRevoked($token->getClaim('jti')); | ||
} | ||
|
||
/** | ||
* Create active introspection response. | ||
* | ||
* @param Token $token | ||
* | ||
* @return IntrospectionResponse | ||
*/ | ||
private function setTokenOnResponse(Token $token, IntrospectionResponse $responseType) | ||
{ | ||
$responseType->setToken($token); | ||
|
||
return $responseType; | ||
} | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.