From 9788ea6b9fb60ce104a7f2d1218e2fd11c07f040 Mon Sep 17 00:00:00 2001 From: Julien Deniau Date: Wed, 22 Aug 2018 09:00:42 +0200 Subject: [PATCH] add documentation --- Controller/IntrospectionController.php | 38 ++++++++----- Resources/doc/index.md | 2 + Resources/doc/introspection_endpoint.md | 76 +++++++++++++++++++++++++ 3 files changed, 101 insertions(+), 15 deletions(-) create mode 100644 Resources/doc/introspection_endpoint.md diff --git a/Controller/IntrospectionController.php b/Controller/IntrospectionController.php index 3e6a1635..d262d1d4 100644 --- a/Controller/IntrospectionController.php +++ b/Controller/IntrospectionController.php @@ -70,21 +70,7 @@ public function __construct( public function introspectAction(Request $request): JsonResponse { - $clientToken = $this->tokenStorage->getToken(); // → use in security - - if (!$clientToken instanceof OAuthToken) { - throw new AccessDeniedException('The introspect endpoint must be behind a secure firewall.'); - } - - $callerToken = $this->accessTokenManager->findTokenByToken($clientToken->getToken()); - - if (!$callerToken) { - throw new AccessDeniedException('The access token must have a valid token.'); - } - - if (!in_array($callerToken->getClientId(), $this->allowedIntrospectionClients)) { - throw new AccessDeniedException('This access token is not autorised to do introspection.'); - } + $this->denyAccessIfNotAuthorizedClient(); $token = $this->getToken($request); @@ -106,6 +92,28 @@ public function introspectAction(Request $request): JsonResponse ]); } + /** + * Check that the caller has a token generated by an allowed client + */ + private function denyAccessIfNotAuthorizedClient(): void + { + $clientToken = $this->tokenStorage->getToken(); + + if (!$clientToken instanceof OAuthToken) { + throw new AccessDeniedException('The introspect endpoint must be behind a secure firewall.'); + } + + $callerToken = $this->accessTokenManager->findTokenByToken($clientToken->getToken()); + + if (!$callerToken) { + throw new AccessDeniedException('The access token must have a valid token.'); + } + + if (!in_array($callerToken->getClientId(), $this->allowedIntrospectionClients)) { + throw new AccessDeniedException('This access token is not autorised to do introspection.'); + } + } + /** * @return TokenInterface|null */ diff --git a/Resources/doc/index.md b/Resources/doc/index.md index 65ac21c4..304a87a8 100644 --- a/Resources/doc/index.md +++ b/Resources/doc/index.md @@ -624,3 +624,5 @@ The `authorize` endpoint is at `/oauth/v2/auth` by default (see `Resources/confi [Adding Grant Extensions](adding_grant_extensions.md) [Custom DB Driver](custom_db_driver.md) + +[Introspection endpoint](introspection_endpoint.md) diff --git a/Resources/doc/introspection_endpoint.md b/Resources/doc/introspection_endpoint.md new file mode 100644 index 00000000..8cad3a80 --- /dev/null +++ b/Resources/doc/introspection_endpoint.md @@ -0,0 +1,76 @@ +Introspection endpoint +========================================= + +The OAuth 2.0 Token Introspection extension defines a protocol that returns information about an access token, intended to be used by resource servers or other internal servers. + +For more information, see [this explaination](https://www.oauth.com/oauth2-servers/token-introspection-endpoint/) or [the RFC 7662](https://tools.ietf.org/html/rfc7662). + +## Configuration + +Import the routing.yml configuration file in `app/config/routing.yml`: + +```yaml +# app/config/routing.yml + +fos_oauth_server_introspection: + resource: "@FOSOAuthServerBundle/Resources/config/routing/introspection.xml" +``` + +Add FOSOAuthServerBundle settings in `app/config/config.yml`: + +```yaml +fos_oauth_server: + introspection: + allowed_clients: + - 1_wUS0gjHdHyC2qeBL3u7RuIrIXClt6irL # an oauth client used only for token introspection. +``` + +The allowed clients MUST be clients as defined [here](index.md#creating-a-client) and SHOULD be used only for token introspection (otherwise a endpoint client might call the introspection endpoint with its valid token). + + +The introspection endpoint must be behind a firewall defined like this: + +```yaml +# app/config/security.yml +security: + firewalls: + oauth_introspect: + host: "%domain.oauth2%" + pattern: ^/oauth/v2/introspect + fos_oauth: true + stateless: true + anonymous: false +``` + +### Usage + +Then you can call the introspection endpoint like this: + +``` +POST /token_info +Host: authorization-server.com +Authorization: Bearer KvIu5v90GqgDctofFXP8npjC5DzMUkci + +token=SON4N82oVuRFykExk0iGTghihgOcI6bm +``` + +The JSON response will look like this if the token is inactive: + +```json +{ + "active": false +} +``` + +If the token is active, the response will look like this: + +```json +{ + "active": true, + "scope": "scope1 scope2", + "client_id": "2_HC1KF0UrawHx05AxgNEeKJF10giBUOHZ", + "username": "foobar", + "token_type": "access_token", + "exp": 1534921182 +} +```