16
16
17
17
class IntrospectionController
18
18
{
19
- /**
20
- * @var \Lcobucci\JWT\Parser
21
- */
22
- private $ jwt ;
23
-
24
- /**
25
- * @var \League\OAuth2\Server\ResourceServer
26
- */
27
- private $ resourceServer ;
28
-
29
- /**
30
- * @var \Laravel\Passport\Bridge\AccessTokenRepository
31
- */
32
- private $ accessTokenRepository ;
33
-
34
- /**
35
- * constructing IntrospectionController
36
- *
37
- * @param \Lcobucci\JWT\Parser $jwt
38
- * @param \League\OAuth2\Server\ResourceServer $resourceServer
39
- * @param \Laravel\Passport\Bridge\AccessTokenRepository $accessTokenRepository
40
- */
41
- public function __construct (
42
- Parser $ jwt ,
43
- ResourceServer $ resourceServer ,
44
- AccessTokenRepository $ accessTokenRepository
45
- ) {
46
- $ this ->jwt = $ jwt ;
47
- $ this ->resourceServer = $ resourceServer ;
48
- $ this ->accessTokenRepository = $ accessTokenRepository ;
49
- }
50
-
51
- /**
52
- * Authorize a client to access the user's account.
53
- *
54
- * @param ServerRequestInterface $request
55
- *
56
- * @return JsonResponse|ResponseInterface
57
- */
58
- public function introspectToken (ServerRequestInterface $ request )
59
- {
60
- try {
61
- $ this ->resourceServer ->validateAuthenticatedRequest ($ request );
62
-
63
- if (array_get ($ request ->getParsedBody (), 'token_type_hint ' , 'access_token ' ) !== 'access_token ' ) {
64
- // unsupported introspection
65
- return $ this ->notActiveResponse ();
66
- }
67
-
68
- $ accessToken = array_get ($ request ->getParsedBody (), 'token ' );
69
- if ($ accessToken === null ) {
70
- return $ this ->notActiveResponse ();
71
- }
72
-
73
- $ token = $ this ->jwt ->parse ($ accessToken );
74
- if ( ! $ this ->verifyToken ($ token )) {
75
- return $ this ->errorResponse ([
76
- 'error ' => [
77
- 'title ' => 'Token invalid '
78
- ]
79
- ]);
80
- }
81
-
82
- /** @var string $userModel */
83
- $ userModel = config ('auth.providers.users.model ' );
84
- $ user = (new $ userModel )->findOrFail ($ token ->getClaim ('sub ' ));
85
-
86
- return $ this ->jsonResponse ([
87
- 'active ' => true ,
88
- 'scope ' => trim (implode (' ' , (array )$ token ->getClaim ('scopes ' , []))),
89
- 'client_id ' => intval ($ token ->getClaim ('aud ' )),
90
- 'username ' => $ user ->email ,
91
- 'token_type ' => 'access_token ' ,
92
- 'exp ' => intval ($ token ->getClaim ('exp ' )),
93
- 'iat ' => intval ($ token ->getClaim ('iat ' )),
94
- 'nbf ' => intval ($ token ->getClaim ('nbf ' )),
95
- 'sub ' => intval ($ token ->getClaim ('sub ' )),
96
- 'aud ' => intval ($ token ->getClaim ('aud ' )),
97
- 'jti ' => $ token ->getClaim ('jti ' ),
98
- ]);
99
- } catch (OAuthServerException $ oAuthServerException ) {
100
- return $ oAuthServerException ->generateHttpResponse (new Psr7Response );
101
- } catch (\Exception $ exception ) {
102
- return $ this ->exceptionResponse ($ exception );
103
- }
104
- }
105
-
106
- /**
107
- * returns inactive token message
108
- *
109
- * @return \Illuminate\Http\JsonResponse
110
- */
111
- private function notActiveResponse (): JsonResponse
112
- {
113
- return $ this ->jsonResponse (['active ' => false ]);
114
- }
115
-
116
- /**
117
- * @param array|mixed $data
118
- * @param int $status
119
- *
120
- * @return \Illuminate\Http\JsonResponse
121
- */
122
- private function jsonResponse ($ data , $ status = 200 ): JsonResponse
123
- {
124
- return new JsonResponse ($ data , $ status );
125
- }
126
-
127
- private function verifyToken (Token $ token ): bool
128
- {
129
- $ signer = new \Lcobucci \JWT \Signer \Rsa \Sha256 ();
130
- $ publicKey = 'file:// ' . Passport::keyPath ('oauth-public.key ' );
131
-
132
- try {
133
- if ( ! $ token ->verify ($ signer , $ publicKey )) {
134
- return false ;
135
- }
136
-
137
- $ data = new ValidationData ();
138
- $ data ->setCurrentTime (time ());
139
-
140
- if ( ! $ token ->validate ($ data )) {
141
- return false ;
142
- }
143
-
144
- // is token revoked?
145
- if ($ this ->accessTokenRepository ->isAccessTokenRevoked ($ token ->getClaim ('jti ' ))) {
146
- return false ;
147
- }
148
-
149
- return true ;
150
- } catch (\Exception $ exception ) {
151
- }
152
-
153
- return false ;
154
- }
155
-
156
- /**
157
- * @param array $data
158
- * @param int $status
159
- *
160
- * @return \Illuminate\Http\JsonResponse
161
- */
162
- private function errorResponse ($ data , $ status = 400 ): JsonResponse
163
- {
164
- return $ this ->jsonResponse ($ data , $ status );
165
- }
166
-
167
- /**
168
- * returns an error
169
- *
170
- * @param \Exception $exception
171
- * @param int $status
172
- *
173
- * @return \Illuminate\Http\JsonResponse
174
- */
175
- private function exceptionResponse (\Exception $ exception , $ status = 500 ): JsonResponse
176
- {
177
- return $ this ->errorResponse ([
178
- 'error ' => [
179
- 'id ' => str_slug (get_class ($ exception ) . ' ' . $ status ),
180
- 'status ' => $ status ,
181
- 'title ' => $ exception ->getMessage (),
182
- 'detail ' => $ exception ->getTraceAsString ()
183
- ],
184
- ], $ status );
185
- }
19
+ /**
20
+ * @var \Lcobucci\JWT\Parser
21
+ */
22
+ private $ jwt ;
23
+
24
+ /**
25
+ * @var \League\OAuth2\Server\ResourceServer
26
+ */
27
+ private $ resourceServer ;
28
+
29
+ /**
30
+ * @var \Laravel\Passport\Bridge\AccessTokenRepository
31
+ */
32
+ private $ accessTokenRepository ;
33
+
34
+ /**
35
+ * constructing IntrospectionController
36
+ *
37
+ * @param \Lcobucci\JWT\Parser $jwt
38
+ * @param \League\OAuth2\Server\ResourceServer $resourceServer
39
+ * @param \Laravel\Passport\Bridge\AccessTokenRepository $accessTokenRepository
40
+ */
41
+ public function __construct (
42
+ Parser $ jwt ,
43
+ ResourceServer $ resourceServer ,
44
+ AccessTokenRepository $ accessTokenRepository
45
+ )
46
+ {
47
+ $ this ->jwt = $ jwt ;
48
+ $ this ->resourceServer = $ resourceServer ;
49
+ $ this ->accessTokenRepository = $ accessTokenRepository ;
50
+ }
51
+
52
+ /**
53
+ * Authorize a client to access the user's account.
54
+ *
55
+ * @param ServerRequestInterface $request
56
+ *
57
+ * @return JsonResponse|ResponseInterface
58
+ */
59
+ public function introspectToken (ServerRequestInterface $ request )
60
+ {
61
+ try {
62
+ $ this ->resourceServer ->validateAuthenticatedRequest ($ request );
63
+
64
+ if (array_get ($ request ->getParsedBody (), 'token_type_hint ' , 'access_token ' ) !== 'access_token ' ) {
65
+ // unsupported introspection
66
+ return $ this ->notActiveResponse ();
67
+ }
68
+
69
+ $ accessToken = array_get ($ request ->getParsedBody (), 'token ' );
70
+ if ($ accessToken === null ) {
71
+ return $ this ->notActiveResponse ();
72
+ }
73
+
74
+ $ token = $ this ->jwt ->parse ($ accessToken );
75
+ if (!$ this ->verifyToken ($ token )) {
76
+ return $ this ->errorResponse ([
77
+ 'error ' => [
78
+ 'title ' => 'Token invalid '
79
+ ]
80
+ ]);
81
+ }
82
+
83
+ /** @var string $userModel */
84
+ $ userModel = config ('auth.providers.users.model ' );
85
+ $ user = (new $ userModel )->findOrFail ($ token ->getClaim ('sub ' ));
86
+
87
+ return $ this ->jsonResponse ([
88
+ 'active ' => true ,
89
+ 'scope ' => trim (implode (' ' , (array )$ token ->getClaim ('scopes ' , []))),
90
+ 'client_id ' => intval ($ token ->getClaim ('aud ' )),
91
+ 'username ' => $ user ->email ,
92
+ 'token_type ' => 'access_token ' ,
93
+ 'exp ' => intval ($ token ->getClaim ('exp ' )),
94
+ 'iat ' => intval ($ token ->getClaim ('iat ' )),
95
+ 'nbf ' => intval ($ token ->getClaim ('nbf ' )),
96
+ 'sub ' => intval ($ token ->getClaim ('sub ' )),
97
+ 'aud ' => intval ($ token ->getClaim ('aud ' )),
98
+ 'jti ' => $ token ->getClaim ('jti ' ),
99
+ ]);
100
+ } catch (OAuthServerException $ oAuthServerException ) {
101
+ return $ oAuthServerException ->generateHttpResponse (new Psr7Response );
102
+ } catch (\Exception $ exception ) {
103
+ return $ this ->exceptionResponse ($ exception );
104
+ }
105
+ }
106
+
107
+ /**
108
+ * returns inactive token message
109
+ *
110
+ * @return \Illuminate\Http\JsonResponse
111
+ */
112
+ private function notActiveResponse () : JsonResponse
113
+ {
114
+ return $ this ->jsonResponse (['active ' => false ]);
115
+ }
116
+
117
+ /**
118
+ * @param array|mixed $data
119
+ * @param int $status
120
+ *
121
+ * @return \Illuminate\Http\JsonResponse
122
+ */
123
+ private function jsonResponse ($ data , $ status = 200 ) : JsonResponse
124
+ {
125
+ return new JsonResponse ($ data , $ status );
126
+ }
127
+
128
+ private function verifyToken (Token $ token ) : bool
129
+ {
130
+ $ signer = new \Lcobucci \JWT \Signer \Rsa \Sha256 ();
131
+ $ publicKey = 'file:// ' . Passport::keyPath ('oauth-public.key ' );
132
+
133
+ try {
134
+ if (!$ token ->verify ($ signer , $ publicKey )) {
135
+ return false ;
136
+ }
137
+
138
+ $ data = new ValidationData ();
139
+ $ data ->setCurrentTime (time ());
140
+
141
+ if (!$ token ->validate ($ data )) {
142
+ return false ;
143
+ }
144
+
145
+ // is token revoked?
146
+ if ($ this ->accessTokenRepository ->isAccessTokenRevoked ($ token ->getClaim ('jti ' ))) {
147
+ return false ;
148
+ }
149
+
150
+ return true ;
151
+ } catch (\Exception $ exception ) {
152
+ }
153
+
154
+ return false ;
155
+ }
156
+
157
+ /**
158
+ * @param array $data
159
+ * @param int $status
160
+ *
161
+ * @return \Illuminate\Http\JsonResponse
162
+ */
163
+ private function errorResponse ($ data , $ status = 400 ) : JsonResponse
164
+ {
165
+ return $ this ->jsonResponse ($ data , $ status );
166
+ }
167
+
168
+ /**
169
+ * returns an error
170
+ *
171
+ * @param \Exception $exception
172
+ * @param int $status
173
+ *
174
+ * @return \Illuminate\Http\JsonResponse
175
+ */
176
+ private function exceptionResponse (\Exception $ exception , $ status = 500 ) : JsonResponse
177
+ {
178
+ return $ this ->errorResponse ([
179
+ 'error ' => [
180
+ 'id ' => str_slug (get_class ($ exception ) . ' ' . $ status ),
181
+ 'status ' => $ status ,
182
+ 'title ' => $ exception ->getMessage (),
183
+ 'detail ' => $ exception ->getTraceAsString ()
184
+ ],
185
+ ], $ status );
186
+ }
186
187
}
0 commit comments