From 86715d6048cb8d9e3e5b67b58ca6415ca18bbfff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Jaussoin?= Date: Wed, 6 Nov 2024 11:29:25 +0100 Subject: [PATCH] Fix FLEXIAPI-239 Ensure to return the correct error codes as stated in the RFC6750 section 3.1 --- CHANGELOG.md | 1 + .../app/Http/Middleware/AuthenticateJWT.php | 20 +++++++++++++++---- .../Feature/AccountJWTAuthenticationTest.php | 10 +++++----- 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b2f2c81..df83bb2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ v1.6 - Fix FLEXIAPI-212 Add CoTURN credentials support in the provisioning - Fix FLEXIAPI-213 Add TURN credentials support in the API as defined in draft-uberti-behave-turn-rest-00 - Fix FLEXIAPI-216 Implement the RFC 8898 partially... for HTTP +- Fix FLEXIAPI-239 Ensure to return the correct error codes as stated in the RFC6750 section 3.1 v1.5 --- diff --git a/flexiapi/app/Http/Middleware/AuthenticateJWT.php b/flexiapi/app/Http/Middleware/AuthenticateJWT.php index 4a2f07e..ef4c393 100644 --- a/flexiapi/app/Http/Middleware/AuthenticateJWT.php +++ b/flexiapi/app/Http/Middleware/AuthenticateJWT.php @@ -41,7 +41,7 @@ class AuthenticateJWT { if ($request->bearerToken() && config('services.jwt.rsa_public_key_pem')) { if (!extension_loaded('sodium')) { - abort(403, "Your PHP setup doesn't have the Sodium extension loaded"); + abort(403, "PHP Sodium extension isn't loaded"); } $publicKey = InMemory::plainText(config('services.jwt.rsa_public_key_pem')); @@ -64,15 +64,15 @@ class AuthenticateJWT } if ($signer == null) { - abort(403, 'Unsupported RSA signature'); + return $this->generateUnauthorizedBearerResponse('invalid_token', 'Unsupported RSA signature'); } if (!(new Validator())->validate($token, new SignedWith($signer, $publicKey))) { - abort(403, 'Invalid JWT token signature'); + return $this->generateUnauthorizedBearerResponse('invalid_token', 'Invalid JWT token signature'); } if ($token->isExpired(new DateTimeImmutable())) { - abort(403, 'Expired JWT token'); + return $this->generateUnauthorizedBearerResponse('invalid_token', 'Expired JWT token'); } $account = null; @@ -114,4 +114,16 @@ class AuthenticateJWT return $next($request); } + + private function generateUnauthorizedBearerResponse(string $error, string $description): Response + { + $response = new Response(); + $response->header( + 'WWW-Authenticate', + 'Bearer error="' . $error .'", "'. $description . '"' + ); + $response->setStatusCode(401); + + return $response; + } } diff --git a/flexiapi/tests/Feature/AccountJWTAuthenticationTest.php b/flexiapi/tests/Feature/AccountJWTAuthenticationTest.php index 1f9b8cd..0d83341 100644 --- a/flexiapi/tests/Feature/AccountJWTAuthenticationTest.php +++ b/flexiapi/tests/Feature/AccountJWTAuthenticationTest.php @@ -129,15 +129,16 @@ class AccountJWTAuthenticationTest extends TestCase ): Builder => $builder->withClaim('email', $password->account->email) ); - $this->withHeaders([ + $response = $this->withHeaders([ 'Authorization' => 'Bearer ' . $token->toString(), 'x-linphone-provisioning' => true, ]) ->get($this->accountRoute) - ->assertStatus(403); + ->assertStatus(401); - // Expired token + $this->assertStringContainsString('invalid_token', $response->headers->get('WWW-Authenticate')); + // Wrong email $token = (new JwtFacade(null, $clock))->issue( new Sha256(), InMemory::plainText($this->serverPrivateKeyPem), @@ -155,7 +156,6 @@ class AccountJWTAuthenticationTest extends TestCase ->assertStatus(403); // Wrong signature key - $keys = openssl_pkey_new(array("private_key_bits" => 4096,"private_key_type" => OPENSSL_KEYTYPE_RSA)); openssl_pkey_export($keys, $wrongServerPrivateKeyPem); @@ -173,7 +173,7 @@ class AccountJWTAuthenticationTest extends TestCase 'x-linphone-provisioning' => true, ]) ->get($this->accountRoute) - ->assertStatus(403); + ->assertStatus(401); } public function testAuthBearerUrl()