Skip to content

Commit a678491

Browse files
committed
Improve JWT implementation
1 parent 8cc997d commit a678491

File tree

3 files changed

+29
-8
lines changed

3 files changed

+29
-8
lines changed

README.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ You can tune the middleware behavior using middleware specific configuration par
162162
- "cors.allowCredentials": To allow credentials in the CORS request ("true")
163163
- "cors.maxAge": The time that the CORS grant is valid in seconds ("1728000")
164164
- "jwtAuth.mode": Set to "optional" if you want to allow anonymous access ("required")
165+
- "jwtAuth.header": Name of the header containing the JWT token ("X-Authorization")
165166
- "jwtAuth.leeway": The acceptable number of seconds of clock skew ("5")
166167
- "jwtAuth.ttl": The number of seconds the token is valid ("30")
167168
- "jwtAuth.secret": The shared secret used to sign the JWT token with ("")
@@ -588,10 +589,12 @@ This example sends the string "username1:password1".
588589

589590
The JWT type requires another (SSO/Identity) server to sign a token that contains claims.
590591
Both servers share a secret so that they can either sign or verify that the signature is valid.
591-
Claims are stored in the `$_SESSION['claims']` variable.
592-
You need to send an "Authorization" header containing a base64 url encoded and dot separated token header, body and signature after the word "Bearer" ([read more about JWT here](https://jwt.io/)).
592+
Claims are stored in the `$_SESSION['claims']` variable. You need to send an "X-Authorization"
593+
header containing a base64 url encoded and dot separated token header, body and signature after
594+
the word "Bearer" ([read more about JWT here](https://jwt.io/)). The standard says you need to
595+
use the "Authorization" header, but this is problematic in Apache and PHP.
593596

594-
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6IjE1MzgyMDc2MDUiLCJleHAiOjE1MzgyMDc2MzV9.Z5px_GT15TRKhJCTHhDt5Z6K6LRDSFnLj8U5ok9l7gw
597+
X-Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6IjE1MzgyMDc2MDUiLCJleHAiOjE1MzgyMDc2MzV9.Z5px_GT15TRKhJCTHhDt5Z6K6LRDSFnLj8U5ok9l7gw
595598

596599
This example sends the signed claims:
597600

api.php

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3194,7 +3194,7 @@ public function handle(Request $request): Response
31943194

31953195
class JwtAuthMiddleware extends Middleware
31963196
{
3197-
private function getVerifiedClaims(String $token, int $time, int $leeway, int $ttl, String $secret): array
3197+
private function getVerifiedClaims(String $token, int $time, int $leeway, int $ttl, String $secret, array $requirements): array
31983198
{
31993199
$algorithms = array('HS256' => 'sha256', 'HS384' => 'sha384', 'HS512' => 'sha512');
32003200
$token = explode('.', $token);
@@ -3221,6 +3221,13 @@ private function getVerifiedClaims(String $token, int $time, int $leeway, int $t
32213221
if (!$claims) {
32223222
return array();
32233223
}
3224+
foreach ($requirements as $field => $values) {
3225+
if (!empty($values)) {
3226+
if (!isset($claims[$field]) || !in_array($claims[$field], $values)) {
3227+
return array();
3228+
}
3229+
}
3230+
}
32243231
if (isset($claims['nbf']) && $time + $leeway < $claims['nbf']) {
32253232
return array();
32263233
}
@@ -3238,21 +3245,32 @@ private function getVerifiedClaims(String $token, int $time, int $leeway, int $t
32383245
return $claims;
32393246
}
32403247

3248+
private function getArrayProperty(String $property, String $default): array
3249+
{
3250+
return array_filter(array_map('trim', explode(',', $this->getProperty($property, $default))));
3251+
}
3252+
32413253
private function getClaims(String $token): array
32423254
{
32433255
$time = (int) $this->getProperty('time', time());
32443256
$leeway = (int) $this->getProperty('leeway', '5');
32453257
$ttl = (int) $this->getProperty('ttl', '30');
32463258
$secret = $this->getProperty('secret', '');
3259+
$requirements = array(
3260+
'alg' => $this->getArrayProperty('algorithms', ''),
3261+
'aud' => $this->getArrayProperty('audiences', ''),
3262+
'iss' => $this->getArrayProperty('issuers', ''),
3263+
);
32473264
if (!$secret) {
32483265
return array();
32493266
}
3250-
return $this->getVerifiedClaims($token, $time, $leeway, $ttl, $secret);
3267+
return $this->getVerifiedClaims($token, $time, $leeway, $ttl, $secret, $requirements);
32513268
}
32523269

32533270
private function getAuthorizationToken(Request $request): String
32543271
{
3255-
$parts = explode(' ', trim($request->getHeader('Authorization')), 2);
3272+
$header = $this->getProperty('header', 'X-Authorization');
3273+
$parts = explode(' ', trim($request->getHeader($header)), 2);
32563274
if (count($parts) != 2) {
32573275
return '';
32583276
}
@@ -5432,7 +5450,6 @@ public function __toString(): String
54325450
'username' => 'php-crud-api',
54335451
'password' => 'php-crud-api',
54345452
'database' => 'php-crud-api',
5435-
'middlewares' => 'basicAuth',
54365453
]);
54375454
$request = new Request();
54385455
$api = new Api($config);

src/Tqdev/PhpCrudApi/Middleware/JwtAuthMiddleware.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,8 @@ private function getClaims(String $token): array
8484

8585
private function getAuthorizationToken(Request $request): String
8686
{
87-
$parts = explode(' ', trim($request->getHeader('Authorization')), 2);
87+
$header = $this->getProperty('header', 'X-Authorization');
88+
$parts = explode(' ', trim($request->getHeader($header)), 2);
8889
if (count($parts) != 2) {
8990
return '';
9091
}

0 commit comments

Comments
 (0)