From 4630759a8f9086a10e7dbce39a7dc5cf5a801718 Mon Sep 17 00:00:00 2001 From: Julien Veyssier Date: Tue, 20 Aug 2024 17:48:58 +0200 Subject: [PATCH] make aud and azp checks optional when logging in or validating a bearer token Signed-off-by: Julien Veyssier --- README.md | 9 +++-- lib/Controller/LoginController.php | 40 ++++++++++++--------- lib/User/Validator/SelfEncodedValidator.php | 4 +++ 3 files changed, 34 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index b0ffd442..e0d8f351 100644 --- a/README.md +++ b/README.md @@ -195,13 +195,16 @@ it is possible to disable the classic "self-encoded" validation: ], ``` -### Disable audience check in bearer token validation +### Disable audience and azp checks -The `audience` and `azp` token claims will be checked when validating a bearer token for authenticated API requests. -You can disable this check with this config value: +The `audience` and `azp` token claims will be checked when validating a login or bearer ID token. +You can disable these check with these config value (in config.php): ``` php 'user_oidc' => [ + 'login_validation_audience_check' => false, + 'login_validation_azp_check' => false, 'selfencoded_bearer_validation_audience_check' => false, + 'selfencoded_bearer_validation_azp_check' => false, ], ``` diff --git a/lib/Controller/LoginController.php b/lib/Controller/LoginController.php index bf4102e6..c5ceb46d 100644 --- a/lib/Controller/LoginController.php +++ b/lib/Controller/LoginController.php @@ -489,23 +489,31 @@ public function code(string $state = '', string $code = '', string $scope = '', } // Verify audience - $tokenAudience = $idTokenPayload->aud; - $providerClientId = $provider->getClientId(); - if ( - (is_string($tokenAudience) && $tokenAudience !== $providerClientId) + $checkAudience = !isset($oidcSystemConfig['login_validation_audience_check']) + || !in_array($oidcSystemConfig['login_validation_audience_check'], [false, 'false', 0, '0'], true); + if ($checkAudience) { + $tokenAudience = $idTokenPayload->aud; + $providerClientId = $provider->getClientId(); + if ( + (is_string($tokenAudience) && $tokenAudience !== $providerClientId) || (is_array($tokenAudience) && !in_array($providerClientId, $tokenAudience, true)) - ) { - $this->logger->debug('This token is not for us'); - $message = $this->l10n->t('The audience does not match ours'); - return $this->build403TemplateResponse($message, Http::STATUS_FORBIDDEN, ['invalid_audience' => $idTokenPayload->aud]); - } - - // ref https://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation - // If the azp claim is present, it should be the client ID - if (isset($idTokenPayload->azp) && $idTokenPayload->azp !== $provider->getClientId()) { - $this->logger->debug('This token is not for us, authorized party (azp) is different than the client ID'); - $message = $this->l10n->t('The authorized party does not match ours'); - return $this->build403TemplateResponse($message, Http::STATUS_FORBIDDEN, ['invalid_azp' => $idTokenPayload->azp]); + ) { + $this->logger->debug('This token is not for us'); + $message = $this->l10n->t('The audience does not match ours'); + return $this->build403TemplateResponse($message, Http::STATUS_FORBIDDEN, ['invalid_audience' => $idTokenPayload->aud]); + } + } + + $checkAzp = !isset($oidcSystemConfig['login_validation_azp_check']) + || !in_array($oidcSystemConfig['login_validation_azp_check'], [false, 'false', 0, '0'], true); + if ($checkAzp) { + // ref https://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation + // If the azp claim is present, it should be the client ID + if (isset($idTokenPayload->azp) && $idTokenPayload->azp !== $provider->getClientId()) { + $this->logger->debug('This token is not for us, authorized party (azp) is different than the client ID'); + $message = $this->l10n->t('The authorized party does not match ours'); + return $this->build403TemplateResponse($message, Http::STATUS_FORBIDDEN, ['invalid_azp' => $idTokenPayload->azp]); + } } if (isset($idTokenPayload->nonce) && $idTokenPayload->nonce !== $this->session->get(self::NONCE)) { diff --git a/lib/User/Validator/SelfEncodedValidator.php b/lib/User/Validator/SelfEncodedValidator.php index 6e479745..b970c45e 100644 --- a/lib/User/Validator/SelfEncodedValidator.php +++ b/lib/User/Validator/SelfEncodedValidator.php @@ -98,7 +98,11 @@ public function isValidBearerToken(Provider $provider, string $bearerToken): ?st $this->logger->debug('This token is not for us, the audience does not match the client ID'); return null; } + } + $checkAzp = !isset($oidcSystemConfig['selfencoded_bearer_validation_azp_check']) + || !in_array($oidcSystemConfig['selfencoded_bearer_validation_azp_check'], [false, 'false', 0, '0'], true); + if ($checkAzp) { // ref https://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation // If the azp claim is present, it should be the client ID if (isset($payload->azp) && $payload->azp !== $providerClientId) {