13
13
14
14
namespace FOS \OAuthServerBundle \Controller ;
15
15
16
+ use FOS \OAuthServerBundle \Form \Model \Introspect ;
17
+ use FOS \OAuthServerBundle \Form \Type \IntrospectionFormType ;
16
18
use FOS \OAuthServerBundle \Model \AccessTokenInterface ;
17
19
use FOS \OAuthServerBundle \Model \RefreshTokenInterface ;
18
20
use FOS \OAuthServerBundle \Model \TokenInterface ;
19
21
use FOS \OAuthServerBundle \Model \TokenManagerInterface ;
22
+ use FOS \OAuthServerBundle \Security \Authentication \Token \OAuthToken ;
23
+ use Symfony \Component \Form \FormFactory ;
20
24
use Symfony \Component \HttpFoundation \JsonResponse ;
21
25
use Symfony \Component \HttpFoundation \Request ;
26
+ use Symfony \Component \HttpKernel \Exception \BadRequestHttpException ;
22
27
use Symfony \Component \Security \Core \Authentication \Token \Storage \TokenStorageInterface ;
28
+ use Symfony \Component \Security \Core \Exception \AccessDeniedException ;
23
29
24
30
class IntrospectionController
25
31
{
@@ -38,21 +44,47 @@ class IntrospectionController
38
44
*/
39
45
private $ refreshTokenManager ;
40
46
47
+ /**
48
+ * @var FormFactory
49
+ */
50
+ private $ formFactory ;
51
+
52
+ /**
53
+ * @var array
54
+ */
55
+ private $ allowedIntrospectionClients ;
56
+
41
57
public function __construct (
42
58
TokenStorageInterface $ tokenStorage ,
43
59
TokenManagerInterface $ accessTokenManager ,
44
- TokenManagerInterface $ refreshTokenManager
60
+ TokenManagerInterface $ refreshTokenManager ,
61
+ FormFactory $ formFactory ,
62
+ array $ allowedIntrospectionClients
45
63
) {
46
64
$ this ->tokenStorage = $ tokenStorage ;
47
65
$ this ->accessTokenManager = $ accessTokenManager ;
48
66
$ this ->refreshTokenManager = $ refreshTokenManager ;
67
+ $ this ->formFactory = $ formFactory ;
68
+ $ this ->allowedIntrospectionClients = $ allowedIntrospectionClients ;
49
69
}
50
70
51
71
public function introspectAction (Request $ request ): JsonResponse
52
72
{
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
+ }
54
78
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
+ }
56
88
57
89
$ token = $ this ->getToken ($ request );
58
90
@@ -79,8 +111,9 @@ public function introspectAction(Request $request): JsonResponse
79
111
*/
80
112
private function getToken (Request $ request )
81
113
{
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 ;
84
117
85
118
$ tokenManagerList = [];
86
119
if (!$ tokenTypeHint || 'access_token ' === $ tokenTypeHint ) {
@@ -125,4 +158,21 @@ private function getUsername(TokenInterface $token)
125
158
126
159
return $ user ->getUserName ();
127
160
}
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
+ }
128
178
}
0 commit comments