From 73eac83afe585fe4777b8dfeb193188d6c59a6b0 Mon Sep 17 00:00:00 2001 From: Dan Brown Date: Fri, 28 Jan 2022 14:00:55 +0000 Subject: [PATCH] Fixed OIDC JWT key parsing in microsoft environments Made existence of 'alg' optional when JWK array set so we instead infer it as RSA256 if not existing. Fixes #3206 --- app/Auth/Access/Oidc/OidcJwtSigningKey.php | 7 ++++-- app/Auth/Access/Oidc/OidcProviderSettings.php | 3 ++- tests/Auth/OidcTest.php | 25 +++++++++++++++++++ 3 files changed, 32 insertions(+), 3 deletions(-) diff --git a/app/Auth/Access/Oidc/OidcJwtSigningKey.php b/app/Auth/Access/Oidc/OidcJwtSigningKey.php index a70f3b3c7..012a6cbf9 100644 --- a/app/Auth/Access/Oidc/OidcJwtSigningKey.php +++ b/app/Auth/Access/Oidc/OidcJwtSigningKey.php @@ -60,8 +60,11 @@ class OidcJwtSigningKey */ protected function loadFromJwkArray(array $jwk) { - if ($jwk['alg'] !== 'RS256') { - throw new OidcInvalidKeyException("Only RS256 keys are currently supported. Found key using {$jwk['alg']}"); + // 'alg' is optional for a JWK, but we will still attempt to validate if + // it exists otherwise presume it will be compatible. + $alg = $jwk['alg'] ?? null; + if ($jwk['kty'] !== 'RSA' || !(is_null($alg) || $alg === 'RS256')) { + throw new OidcInvalidKeyException("Only RS256 keys are currently supported. Found key using {$alg}"); } if (empty($jwk['use'])) { diff --git a/app/Auth/Access/Oidc/OidcProviderSettings.php b/app/Auth/Access/Oidc/OidcProviderSettings.php index 32946d058..016d006d2 100644 --- a/app/Auth/Access/Oidc/OidcProviderSettings.php +++ b/app/Auth/Access/Oidc/OidcProviderSettings.php @@ -164,7 +164,8 @@ class OidcProviderSettings protected function filterKeys(array $keys): array { return array_filter($keys, function (array $key) { - return $key['kty'] === 'RSA' && $key['use'] === 'sig' && $key['alg'] === 'RS256'; + $alg = $key['alg'] ?? null; + return $key['kty'] === 'RSA' && $key['use'] === 'sig' && (is_null($alg) || $alg === 'RS256'); }); } diff --git a/tests/Auth/OidcTest.php b/tests/Auth/OidcTest.php index 0b033ea81..9fa4d0012 100644 --- a/tests/Auth/OidcTest.php +++ b/tests/Auth/OidcTest.php @@ -318,6 +318,31 @@ class OidcTest extends TestCase $this->assertCount(4, $transactions); } + public function test_auth_login_with_autodiscovery_with_keys_that_do_not_have_alg_property() + { + $this->withAutodiscovery(); + + $keyArray = OidcJwtHelper::publicJwkKeyArray(); + unset($keyArray['alg']); + + $this->mockHttpClient([ + $this->getAutoDiscoveryResponse(), + new Response(200, [ + 'Content-Type' => 'application/json', + 'Cache-Control' => 'no-cache, no-store', + 'Pragma' => 'no-cache', + ], json_encode([ + 'keys' => [ + $keyArray, + ], + ])), + ]); + + $this->assertFalse(auth()->check()); + $this->runLogin(); + $this->assertTrue(auth()->check()); + } + protected function withAutodiscovery() { config()->set([