From 47617d1e070dfaf2a7868ea68f69ea1475be304c Mon Sep 17 00:00:00 2001 From: Tim Otten Date: Mon, 9 Nov 2020 16:43:39 -0800 Subject: [PATCH] dev/mail#79 - Add option to get resource-owner via OpenID Connect At time of writing, there appears to be a problem in Microsoft's services: if you request both `User.Read` and `IMAP.AccessAsUser.All`, then the token does not actually work for IMAP access. However, it is does work to combine `openid` and `IMAP.AccessAsUser.All`. This patch to CiviGenericProvider makes it easier to get resource-owner details via OpenID Connect's `id_token`. --- .../Civi/OAuth/CiviGenericProvider.php | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/ext/oauth-client/Civi/OAuth/CiviGenericProvider.php b/ext/oauth-client/Civi/OAuth/CiviGenericProvider.php index 677c21d6fd..8bff0ffb38 100644 --- a/ext/oauth-client/Civi/OAuth/CiviGenericProvider.php +++ b/ext/oauth-client/Civi/OAuth/CiviGenericProvider.php @@ -1,6 +1,23 @@ getResourceOwnerDetailsUrl($token); + + // If there is no resource-owner URL, and if there is an id_token, use it. + if ($url === '{{use_id_token}}') { + $tokenData = $token->jsonSerialize(); + if (isset($tokenData['id_token'])) { + $idToken = $this->decodeUnauthenticatedJwt($tokenData['id_token']); + + // As long as id_token comes from a secure source, we can skip signature check. + // Which is fortunate... because we don't what key to check against... + if (!preg_match(';^https:;', $this->getBaseAccessTokenUrl([]))) { + throw new \RuntimeException("Cannot decode ID token from insecure source."); + } + + return $idToken['payload']; + } + } + + return parent::fetchResourceOwnerDetails($token); + } + + private function decodeUnauthenticatedJwt($t) { + list ($header, $payload) = explode('.', $t); + + return [ + 'header' => json_decode(base64_decode($header), 1), + 'payload' => json_decode(base64_decode($payload), 1), + ]; + } + } -- 2.25.1