Skip to content

Commit 975066c

Browse files
committed
POC introspection endpoint RFC 7662
1 parent e12b077 commit 975066c

File tree

4 files changed

+146
-0
lines changed

4 files changed

+146
-0
lines changed

Diff for: Controller/IntrospectionController.php

+112
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* This file is part of the FOSOAuthServerBundle package.
7+
*
8+
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
9+
*
10+
* For the full copyright and license information, please view the LICENSE
11+
* file that was distributed with this source code.
12+
*/
13+
14+
namespace FOS\OAuthServerBundle\Controller;
15+
16+
// use FOS\OAuthServerBundle\Model\AccessTokenManagerInterface;
17+
// use FOS\OAuthServerBundle\Model\RefreshTokenManagerInterface;
18+
use FOS\OAuthServerBundle\Model\AccessTokenInterface;
19+
use FOS\OAuthServerBundle\Model\RefreshTokenInterface;
20+
use FOS\OAuthServerBundle\Model\TokenManagerInterface;
21+
use OAuth2\OAuth2;
22+
use OAuth2\OAuth2ServerException;
23+
use Symfony\Component\HttpFoundation\JsonResponse;
24+
use Symfony\Component\HttpFoundation\Request;
25+
use Symfony\Component\HttpFoundation\Response;
26+
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
27+
28+
class IntrospectionController
29+
{
30+
/**
31+
* @var TokenStorageInterface
32+
*/
33+
private $tokenStorage;
34+
35+
/**
36+
* @var TokenManagerInterface
37+
*/
38+
private $accessTokenManager;
39+
40+
/**
41+
* @var TokenManagerInterface
42+
*/
43+
private $refreshTokenManager;
44+
45+
public function __construct(
46+
TokenStorageInterface $tokenStorage,
47+
TokenManagerInterface $accessTokenManager,
48+
TokenManagerInterface $refreshTokenManager
49+
) {
50+
$this->tokenStorage = $tokenStorage;
51+
$this->accessTokenManager = $accessTokenManager;
52+
$this->refreshTokenManager = $refreshTokenManager;
53+
}
54+
55+
/**
56+
* @param Request $request
57+
*
58+
* @return Response
59+
*/
60+
public function introspectAction(Request $request)
61+
{
62+
// $clientToken = $this->tokenStorage->getToken(); → use in security
63+
64+
// TODO security for this endpoint. Probably in the README documentation
65+
$tokenString = $request->request->get('token'); // TODO move in a form type ?
66+
$tokenTypeHint = $request->request->get('token_type_hint'); // TODO move in a form type ? can be `access_token`, `refresh_token` See https://tools.ietf.org/html/rfc7009#section-4.1.2
67+
68+
$tokenManagerList = [];
69+
if (!$tokenTypeHint || 'access_token' === $tokenTypeHint) {
70+
$tokenManagerList[] = $this->accessTokenManager;
71+
}
72+
if (!$tokenTypeHint || 'refresh_token' === $tokenTypeHint) {
73+
$tokenManagerList[] = $this->refreshTokenManager;
74+
}
75+
76+
foreach ($tokenManagerList as $tokenManager) {
77+
$token = $tokenManager->findTokenByToken($tokenString);
78+
79+
if ($token) {
80+
break;
81+
}
82+
}
83+
84+
$isActive = $token && !$token->hasExpired();
85+
86+
if (!$isActive) {
87+
return new JsonResponse([
88+
'active' => false,
89+
]);
90+
}
91+
92+
$user = $token->getUser();
93+
94+
if ($token instanceof AccessTokenInterface) {
95+
$tokenType = 'access_token';
96+
} elseif ($token instanceof RefreshTokenInterface) {
97+
$tokenType = 'refresh_token';
98+
} else {
99+
$tokenType = null;
100+
}
101+
102+
103+
return new JsonResponse([
104+
'active' => true,
105+
'scope' => $token->getScope(),
106+
'client_id' => $token->getClientId(),
107+
'username' => $user ? $user->getUserName() : null,
108+
'token_type' => $tokenType,
109+
'exp' => $token->getExpiresAt(),
110+
]);
111+
}
112+
}

Diff for: DependencyInjection/FOSOAuthServerExtension.php

+7
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,8 @@ public function load(array $configs, ContainerBuilder $container)
101101
$authorizeFormDefinition = $container->getDefinition('fos_oauth_server.authorize.form');
102102
$authorizeFormDefinition->setFactory([new Reference('form.factory'), 'createNamed']);
103103
}
104+
105+
$this->loadIntrospection($loader);
104106
}
105107

106108
/**
@@ -142,6 +144,11 @@ protected function remapParametersNamespaces(array $config, ContainerBuilder $co
142144
}
143145
}
144146

147+
protected function loadIntrospection(XmlFileLoader $loader)
148+
{
149+
$loader->load('introspection.xml');
150+
}
151+
145152
protected function loadAuthorize(array $config, ContainerBuilder $container, XmlFileLoader $loader)
146153
{
147154
$loader->load('authorize.xml');

Diff for: Resources/config/introspection.xml

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?xml version="1.0" encoding="UTF-8" ?>
2+
3+
<container xmlns="http://symfony.com/schema/dic/services"
4+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5+
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
6+
7+
<services>
8+
<service id="fos_oauth_server.controller.introspection" class="FOS\OAuthServerBundle\Controller\IntrospectionController" public="true">
9+
<argument type="service" id="security.token_storage" />
10+
<argument type="service" id="fos_oauth_server.access_token_manager" />
11+
<argument type="service" id="fos_oauth_server.refresh_token_manager" />
12+
</service>
13+
</services>
14+
15+
</container>

Diff for: Resources/config/routing/introspection.xml

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?xml version="1.0" encoding="UTF-8" ?>
2+
3+
<routes xmlns="http://symfony.com/schema/routing"
4+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5+
xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd">
6+
7+
<route id="fos_oauth_server_introspection" path="/oauth/v2/introspect" methods="POST">
8+
<default key="_controller">fos_oauth_server.controller.introspection:introspectAction</default>
9+
</route>
10+
11+
</routes>
12+

0 commit comments

Comments
 (0)