From 133feb102fec71f606581f6b09d3f933355680ee Mon Sep 17 00:00:00 2001 From: ramonschriks Date: Tue, 9 Jan 2024 17:40:49 +0100 Subject: [PATCH 1/2] Update Token.php Fix in not falling through exception after fallback validator succeeded... Signed-off-by: ramonschriks --- src/Token.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Token.php b/src/Token.php index 7ed7101f..f4a91895 100644 --- a/src/Token.php +++ b/src/Token.php @@ -281,9 +281,9 @@ public function validate( } catch (InvalidTokenException $invalidTokenException) { if ($tenantDomain !== $tokenIssuer) { $validator->issuer($tenantDomain); + } else { + throw $invalidTokenException; } - - throw $invalidTokenException; } $validator From 171c66712ae8e374bd9c398e6477160ec2066d82 Mon Sep 17 00:00:00 2001 From: Ramon Date: Tue, 9 Jan 2024 21:33:58 +0100 Subject: [PATCH 2/2] test(added unit tests for validating tokens with issuer claims -> fallback to tenant domain in case of custom domain) --- tests/Unit/TokenTest.php | 76 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/tests/Unit/TokenTest.php b/tests/Unit/TokenTest.php index 3c1ba6a0..6442046a 100644 --- a/tests/Unit/TokenTest.php +++ b/tests/Unit/TokenTest.php @@ -272,6 +272,42 @@ function(): SdkConfiguration { fn() => TokenGenerator::create(TokenGenerator::TOKEN_LOGOUT, TokenGenerator::ALG_HS256, ['events' => null]) ]])->throws(InvalidTokenException::class, InvalidTokenException::MSG_MISSING_EVENTS_CLAIM); +it('fails validating a Logout Token with a mismatch `issuer` claim', function( + SdkConfiguration $configuration, + TokenGeneratorResponse $jwt +): void { + $token = new Token($configuration, $jwt->token, Token::TYPE_LOGOUT_TOKEN); + $token->validate(); +})->with(['mocked hs256 access token' => [ + function(): SdkConfiguration { + $this->configuration->setDomain('invalid-domain.test'); + $this->configuration->setClientId('__test_client_id__'); + $this->configuration->setTokenAlgorithm('HS256'); + $this->configuration->setClientSecret('__test_client_secret__'); + return $this->configuration; + }, + fn() => TokenGenerator::create(TokenGenerator::TOKEN_LOGOUT, TokenGenerator::ALG_HS256) +]])->throws(InvalidTokenException::class, sprintf(InvalidTokenException::MSG_MISMATCHED_ISS_CLAIM, "https://invalid-domain.test/", "https://domain.test/")); + +it('fails validating a Logout Token with a mismatch `issuer` claim with custom domain', function( + SdkConfiguration $configuration, + TokenGeneratorResponse $jwt +): void { + $token = new Token($configuration, $jwt->token, Token::TYPE_LOGOUT_TOKEN); + $token->validate(); +})->with(['mocked hs256 access token' => [ + function(): SdkConfiguration { + $this->configuration->setDomain('invalid-domain.test'); + $this->configuration->setCustomDomain('invalid-custom-domain.test'); + $this->configuration->setClientId('__test_client_id__'); + $this->configuration->setTokenAlgorithm('HS256'); + $this->configuration->setClientSecret('__test_client_secret__'); + return $this->configuration; + }, + fn() => TokenGenerator::create(TokenGenerator::TOKEN_LOGOUT, TokenGenerator::ALG_HS256) +]])->throws(InvalidTokenException::class, sprintf(InvalidTokenException::MSG_MISMATCHED_ISS_CLAIM, "https://invalid-domain.test/", "https://domain.test/")); + + it('fails validating a Logout Token with a malformed `events` claim', function( SdkConfiguration $configuration, TokenGeneratorResponse $jwt @@ -338,6 +374,46 @@ function(): SdkConfiguration { fn() => ['nonce' => '__test_nonce__'] ]]); +test('validate() with custom domain as token issuer fails, but succeeds with tenant domain', function( + SdkConfiguration $configuration, + TokenGeneratorResponse $jwt, + array $claims +): void { + $token = new Token($configuration, $jwt->token, Token::TYPE_ID_TOKEN); + expect($token->validate(null, null, ['org_123'], $claims['nonce'], 100))->toEqual($token); +})->with(['mocked data' => [ + function(): SdkConfiguration { + $this->configuration->setDomain('domain.test'); + $this->configuration->setCustomDomain('not-the-issuer.domain'); + $this->configuration->setClientId('__test_client_id__'); + $this->configuration->setTokenAlgorithm('HS256'); + $this->configuration->setClientSecret('__test_client_secret__'); + return $this->configuration; + }, + fn() => TokenGenerator::create(TokenGenerator::TOKEN_ID, TokenGenerator::ALG_HS256, ['org_id' => 'org_123']), + fn() => ['nonce' => '__test_nonce__'] +]]); + +test('validate() with custom domain as token issuer succeeds, tenant domain is thereby irrelevant', function( + SdkConfiguration $configuration, + TokenGeneratorResponse $jwt, + array $claims +): void { + $token = new Token($configuration, $jwt->token, Token::TYPE_ID_TOKEN); + expect($token->validate(null, null, ['org_123'], $claims['nonce'], 100))->toEqual($token); +})->with(['mocked data' => [ + function(): SdkConfiguration { + $this->configuration->setDomain('invalid-domain.test'); + $this->configuration->setCustomDomain('domain.test'); + $this->configuration->setClientId('__test_client_id__'); + $this->configuration->setTokenAlgorithm('HS256'); + $this->configuration->setClientSecret('__test_client_secret__'); + return $this->configuration; + }, + fn() => TokenGenerator::create(TokenGenerator::TOKEN_ID, TokenGenerator::ALG_HS256, ['org_id' => 'org_123']), + fn() => ['nonce' => '__test_nonce__'] +]]); + test('validate() overrides globally configured algorithm', function( SdkConfiguration $configuration, TokenGeneratorResponse $jwt,