Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add issuer, audience and azp checks in bearer token validator #864

Merged
merged 3 commits into from
Jun 7, 2024

Conversation

julien-nc
Copy link
Member

The bearer token validation is less complete than the login controller one.

  • add issuer, audience and azp (authorized party) checks in bearer token validator
  • make it possible to disable bearer token audience check via config.php.

closes #856

@julien-nc julien-nc added enhancement New feature or request 3. to review labels May 10, 2024
@julien-nc julien-nc force-pushed the enh/856/add-bearer-token-audience-check branch from 99ea021 to bc823aa Compare May 10, 2024 09:39
return null;
}
} else {
$this->logger->debug('Multiple audiences but no authorized party (azp) in the id token');
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
$this->logger->debug('Multiple audiences but no authorized party (azp) in the id token');
$this->logger->debug('Multiple audiences but no authorized party (azp) in the access token');

or simple token may be?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ID tokens are JWT tokens. Access tokens are more or less equivalent to OAuth tokens. This log message is correct IMO.

lib/User/Validator/SelfEncodedValidator.php Outdated Show resolved Hide resolved
$checkAudience = !isset($oidcSystemConfig['selfencoded_bearer_validation_audience_check'])
|| !in_array($oidcSystemConfig['selfencoded_bearer_validation_audience_check'], [false, 'false', 0, '0'], true);
if ($checkAudience) {
if (!($payload->aud === $provider->getClientId() || in_array($provider->getClientId(), $payload->aud, true))) {
Copy link

@SagarGi SagarGi May 23, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hi @julien-nc I check out this PR. In case we have a single audience in the access token other than nextcloud.
for example i tried to make request with with access token:

   "aud": "client_other_than_nextcloud"

i got server error with status code 500 as:

<?xml version="1.0" encoding="utf-8"?>
<d:error xmlns:d="DAV:" xmlns:s="http://sabredav.org/ns">
    <s:exception>TypeError</s:exception>
    <s:message>in_array(): Argument #2 ($haystack) must be of type array, string given</s:message>
</d:error>

It seems like it is checking for multiple audience as an array but for single we have only string. Might be the reason for the error?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Audience can be a string or an array. The check is now safer. Any better?

@julien-nc julien-nc force-pushed the enh/856/add-bearer-token-audience-check branch from bc823aa to 022ff1a Compare May 23, 2024 15:15
@julien-nc julien-nc force-pushed the enh/856/add-bearer-token-audience-check branch from 022ff1a to 6984473 Compare June 3, 2024 11:22
@julien-nc
Copy link
Member Author

@wielinde Could you say again what was your concern about the azp check?

The current check (when validating the token for API calls) is:
If there are multiple audiences in the token (the aud attribute of the token is an array), we want the azp token attribute (authorized party) to be equal to the Oidc client ID.

This was implemented following points 4 and 5 of https://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation

Do you think this check only makes sense to authenticate in NC but not when validating a token used to make API calls?

@wielinde
Copy link

wielinde commented Jun 3, 2024

@julien-nc I understand the specification that you have linked above in the following manner:

Only when there is an azp is given, then it shall be taken into account. However, that it is present in a token is not the default. In a vanilla OIDC setup, the azp shall not be added to a token, unless required by a OIDC extension.

And I am not aware of any such OIDC extension. So from my understanding, I would remove the requirement that the an azp must be given whenever an array of aud is present. And when azp is given, then it needs to be in the list auf aud AND be the Nextcloud client. Does that make sense?

// FYI @ba1ash

@julien-nc
Copy link
Member Author

julien-nc commented Jun 4, 2024

@wielinde I can't remember where I found a different description of how the azp check should be done. Anyway let's stick to this one.
For both login token and bearer token, the check is now: (Independently of the aud claim) If the token has the azp claim, it should be equal to the Oidc client ID.
If audience check is disabled for bearer token validation, the azp is not checked even if it's present.

All good?

@wielinde
Copy link

wielinde commented Jun 4, 2024

@julien-nc From my understanding of the spec, that looks good, now. Thank you.

@julien-nc julien-nc requested a review from SagarGi June 7, 2024 09:52
…ake it possible to disable audience check via config

Signed-off-by: Julien Veyssier <[email protected]>
Signed-off-by: Julien Veyssier <[email protected]>
@julien-nc julien-nc force-pushed the enh/856/add-bearer-token-audience-check branch from 8cdbd7e to 91e7712 Compare June 7, 2024 10:00
Copy link
Member

@juliusknorr juliusknorr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code looks good 👍

@julien-nc julien-nc merged commit a3980ce into main Jun 7, 2024
38 checks passed
@julien-nc julien-nc deleted the enh/856/add-bearer-token-audience-check branch June 7, 2024 13:56
@julien-nc julien-nc mentioned this pull request Jun 21, 2024
@col-panic
Copy link

I'm using user_oidc to protect my API. Now since this patch, I cannot access Nextcloud using API anymore, the output is This token is not for us, authorized party (azp) is different than the client ID

I found the setting selfencoded_bearer_validation_audience_check but it seems to catch only when coming in via https://github.com/nextcloud/user_oidc/blob/f5bb30caef3a31ba19fe3f44da256b46cac90e9f/lib/User/Validator/SelfEncodedValidator.php#L90 not when coming in via

$this->logger->debug('This token is not for us, authorized party (azp) is different than the client ID');

Check for example https://github.com/search?q=repo%3Anextcloud%2Fuser_oidc+%22This+token+is+not+for+us%2C+authorized+party+%28azp%29+is+different+than+the+client+ID%22&type=code

Could you please verify, that this option does also disable azp and aud checkin when used via API?

Should I create a new issue for this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
3. to review enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Audience claim verification check with Bearer token
5 participants