From 17f7afe12d617358ba59489fb544f339839e7370 Mon Sep 17 00:00:00 2001 From: Wes Biggs Date: Tue, 26 Nov 2024 11:21:20 -0600 Subject: [PATCH 1/2] Updates the OIDC userinfo endpoint request to allow for a `Content-Type` response header with optional parameters, like `application/json; charset=utf-8`. This was causing an issue when integrating with [node-oidc-provider](https://github.com/panva/node-oidc-provider). --- app/Access/Oidc/OidcUserinfoResponse.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Access/Oidc/OidcUserinfoResponse.php b/app/Access/Oidc/OidcUserinfoResponse.php index 9aded654e..ffcacb8de 100644 --- a/app/Access/Oidc/OidcUserinfoResponse.php +++ b/app/Access/Oidc/OidcUserinfoResponse.php @@ -11,7 +11,7 @@ class OidcUserinfoResponse implements ProvidesClaims public function __construct(ResponseInterface $response, string $issuer, array $keys) { - $contentType = $response->getHeader('Content-Type')[0]; + $contentType = explode(';', $response->getHeader('Content-Type')[0], 2)[0]; if ($contentType === 'application/json') { $this->claims = json_decode($response->getBody()->getContents(), true); } From bc1f1d92e52ef5b103bdcbd739a001aece605b5d Mon Sep 17 00:00:00 2001 From: Dan Brown Date: Thu, 28 Nov 2024 16:58:06 +0000 Subject: [PATCH 2/2] OIDC: Added extra userinfo content-type normalisation and test During review of #5337 --- app/Access/Oidc/OidcUserinfoResponse.php | 4 +++- tests/Auth/OidcTest.php | 14 ++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/app/Access/Oidc/OidcUserinfoResponse.php b/app/Access/Oidc/OidcUserinfoResponse.php index ffcacb8de..33b8ec806 100644 --- a/app/Access/Oidc/OidcUserinfoResponse.php +++ b/app/Access/Oidc/OidcUserinfoResponse.php @@ -11,7 +11,9 @@ class OidcUserinfoResponse implements ProvidesClaims public function __construct(ResponseInterface $response, string $issuer, array $keys) { - $contentType = explode(';', $response->getHeader('Content-Type')[0], 2)[0]; + $contentTypeHeaderValue = $response->getHeader('Content-Type')[0] ?? ''; + $contentType = strtolower(trim(explode(';', $contentTypeHeaderValue, 2)[0])); + if ($contentType === 'application/json') { $this->claims = json_decode($response->getBody()->getContents(), true); } diff --git a/tests/Auth/OidcTest.php b/tests/Auth/OidcTest.php index 201f67b53..205f75a4d 100644 --- a/tests/Auth/OidcTest.php +++ b/tests/Auth/OidcTest.php @@ -787,6 +787,20 @@ class OidcTest extends TestCase $this->assertTrue($user->hasRole($roleA->id)); } + public function test_userinfo_endpoint_response_with_complex_json_content_type_handled() + { + $userinfoResponseData = [ + 'sub' => OidcJwtHelper::defaultPayload()['sub'], + 'name' => 'Barry', + ]; + $userinfoResponse = new Response(200, ['Content-Type' => 'Application/Json ; charset=utf-8'], json_encode($userinfoResponseData)); + $resp = $this->runLogin(['name' => null], [$userinfoResponse]); + $resp->assertRedirect('/'); + + $user = User::where('email', OidcJwtHelper::defaultPayload()['email'])->first(); + $this->assertEquals('Barry', $user->name); + } + public function test_userinfo_endpoint_jwks_response_handled() { $userinfoResponseData = OidcJwtHelper::idToken(['name' => 'Barry Jwks']);