Skip to content

Commit 2dea4a6

Browse files
committed
add list of allow client for introspection endpoint
1 parent 53e9199 commit 2dea4a6

File tree

4 files changed

+83
-7
lines changed

4 files changed

+83
-7
lines changed

Controller/IntrospectionController.php

+55-5
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,19 @@
1313

1414
namespace FOS\OAuthServerBundle\Controller;
1515

16+
use FOS\OAuthServerBundle\Form\Model\Introspect;
17+
use FOS\OAuthServerBundle\Form\Type\IntrospectionFormType;
1618
use FOS\OAuthServerBundle\Model\AccessTokenInterface;
1719
use FOS\OAuthServerBundle\Model\RefreshTokenInterface;
1820
use FOS\OAuthServerBundle\Model\TokenInterface;
1921
use FOS\OAuthServerBundle\Model\TokenManagerInterface;
22+
use FOS\OAuthServerBundle\Security\Authentication\Token\OAuthToken;
23+
use Symfony\Component\Form\FormFactory;
2024
use Symfony\Component\HttpFoundation\JsonResponse;
2125
use Symfony\Component\HttpFoundation\Request;
26+
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
2227
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
28+
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
2329

2430
class IntrospectionController
2531
{
@@ -38,21 +44,47 @@ class IntrospectionController
3844
*/
3945
private $refreshTokenManager;
4046

47+
/**
48+
* @var FormFactory
49+
*/
50+
private $formFactory;
51+
52+
/**
53+
* @var array
54+
*/
55+
private $allowedIntrospectionClients;
56+
4157
public function __construct(
4258
TokenStorageInterface $tokenStorage,
4359
TokenManagerInterface $accessTokenManager,
44-
TokenManagerInterface $refreshTokenManager
60+
TokenManagerInterface $refreshTokenManager,
61+
FormFactory $formFactory,
62+
array $allowedIntrospectionClients
4563
) {
4664
$this->tokenStorage = $tokenStorage;
4765
$this->accessTokenManager = $accessTokenManager;
4866
$this->refreshTokenManager = $refreshTokenManager;
67+
$this->formFactory = $formFactory;
68+
$this->allowedIntrospectionClients = $allowedIntrospectionClients;
4969
}
5070

5171
public function introspectAction(Request $request): JsonResponse
5272
{
53-
// $clientToken = $this->tokenStorage->getToken(); → use in security
73+
$clientToken = $this->tokenStorage->getToken(); // → use in security
74+
75+
if (!$clientToken instanceof OAuthToken) {
76+
throw new AccessDeniedException('The introspect endpoint must be behind a secure firewall.');
77+
}
5478

55-
// TODO security for this endpoint. Probably in the README documentation
79+
$callerToken = $this->accessTokenManager->findTokenByToken($clientToken->getToken());
80+
81+
if (!$callerToken) {
82+
throw new AccessDeniedException('The access token must have a valid token.');
83+
}
84+
85+
if (!in_array($callerToken->getClientId(), $this->allowedIntrospectionClients)) {
86+
throw new AccessDeniedException('This access token is not autorised to do introspection.');
87+
}
5688

5789
$token = $this->getToken($request);
5890

@@ -79,8 +111,9 @@ public function introspectAction(Request $request): JsonResponse
79111
*/
80112
private function getToken(Request $request)
81113
{
82-
$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
83-
$tokenString = $request->request->get('token'); // TODO move in a form type ?
114+
$formData = $this->processIntrospectionForm($request);
115+
$tokenString = $formData->token;
116+
$tokenTypeHint = $formData->token_type_hint;
84117

85118
$tokenManagerList = [];
86119
if (!$tokenTypeHint || 'access_token' === $tokenTypeHint) {
@@ -125,4 +158,21 @@ private function getUsername(TokenInterface $token)
125158

126159
return $user->getUserName();
127160
}
161+
162+
private function processIntrospectionForm(Request $request): Introspect
163+
{
164+
$formData = new Introspect();
165+
$form = $this->formFactory->create(IntrospectionFormType::class, $formData);
166+
$form->handleRequest($request);
167+
168+
if (!$form->isSubmitted() || !$form->isValid()) {
169+
$errors = $form->getErrors();
170+
if (count($errors) > 0) {
171+
throw new BadRequestHttpException((string) $errors);
172+
} else {
173+
throw new BadRequestHttpException('Introspection endpoint needs to have at least a "token" form parameter');
174+
}
175+
}
176+
return $form->getData();
177+
}
128178
}

DependencyInjection/Configuration.php

+21
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ public function getConfigTreeBuilder()
8282
$this->addAuthorizeSection($rootNode);
8383
$this->addServiceSection($rootNode);
8484
$this->addTemplateSection($rootNode);
85+
$this->addIntrospectionSection($rootNode);
8586

8687
return $treeBuilder;
8788
}
@@ -151,4 +152,24 @@ private function addTemplateSection(ArrayNodeDefinition $node)
151152
->end()
152153
;
153154
}
155+
156+
private function addIntrospectionSection(ArrayNodeDefinition $node)
157+
{
158+
$node
159+
->addDefaultsIfNotSet()
160+
->children()
161+
->arrayNode('introspection')
162+
->addDefaultsIfNotSet()
163+
->children()
164+
->arrayNode('allowed_clients')
165+
->useAttributeAsKey('key')
166+
->treatNullLike([])
167+
->prototype('variable')->end()
168+
->end()
169+
->end()
170+
->end()
171+
->end()
172+
->end()
173+
;
174+
}
154175
}

DependencyInjection/FOSOAuthServerExtension.php

+5-2
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ public function load(array $configs, ContainerBuilder $container)
102102
$authorizeFormDefinition->setFactory([new Reference('form.factory'), 'createNamed']);
103103
}
104104

105-
$this->loadIntrospection($loader);
105+
$this->loadIntrospection($config, $container, $loader);
106106
}
107107

108108
/**
@@ -144,9 +144,12 @@ protected function remapParametersNamespaces(array $config, ContainerBuilder $co
144144
}
145145
}
146146

147-
protected function loadIntrospection(XmlFileLoader $loader)
147+
protected function loadIntrospection(array $config, ContainerBuilder $container, XmlFileLoader $loader)
148148
{
149149
$loader->load('introspection.xml');
150+
151+
$allowedClients = $config['introspection']['allowed_clients'];
152+
$container->setParameter('fos_oauth_server.introspection.allowed_clients', $allowedClients);
150153
}
151154

152155
protected function loadAuthorize(array $config, ContainerBuilder $container, XmlFileLoader $loader)

Resources/config/introspection.xml

+2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
<argument type="service" id="security.token_storage" />
1010
<argument type="service" id="fos_oauth_server.access_token_manager" />
1111
<argument type="service" id="fos_oauth_server.refresh_token_manager" />
12+
<argument type="service" id="form.factory" />
13+
<argument>%fos_oauth_server.introspection.allowed_clients%</argument>
1214
</service>
1315
</services>
1416

0 commit comments

Comments
 (0)