Audience claim verification check with Bearer token
SagarGi opened this issue · 14 comments
Description
I am currently in a situation where i have an access_token
for nextcloud
which i got from keycloak
. The user_oidc
app allows a setting to make API request as bearer-auth using the access_token
. In the access_token
i have an audience claim for example another-client
other than nextcloud
itself.
for example:
{
"exp": 1714648426,
"iat": 1714647826,
"auth_time": 1714647781,
"jti": "8ebabf79-7a87-4c74-86fe-58e24300677b",
"iss": "https://keycloak.local/realms/opendesk",
`"aud": "https://openproject.local"`,
"sub": "6b65f442-e0a2-4e2d-ac0a-32506dd57f41",
"typ": "Bearer",
"azp": "nextcloud",
"session_state": "28b06352-4cb6-4fca-9487-11795e1ec7a2",
}
In the above payload of the access_token
the audience claim is "aud": "https://openproject.local"
which is not nextcloud
. And i am able to make API request with it.
I have some question regarding it.
- Does the
user_oidc
app check and verify the audience claim in theaccess_token
for API request? - Or the
user_oidc
is missing to check the audience claim? - Or its intended feature?
- Or any other reasons why the audience claim is not checked and verified when making API request?
Does the user_oidc app check and verify the audience claim in the access_token for API request?
No, only the token expiration is checked: https://github.com/nextcloud/user_oidc/blob/main/lib/User/Validator/SelfEncodedValidator.php#L67-L71
There are many more checks done when obtaining a token during login: https://github.com/nextcloud/user_oidc/blob/main/lib/Controller/LoginController.php#L444-L484
It is kind of intended. I mean, the goal is to let other services (using the same client from the same IdP) make API requests to NC.
Why are you asking? Do you expect the validation to fail in this case?
@julien-nc Any other services making request with the nextcloud
with any audience claim seemed a bit odd. Also i might lack knowledge why the audience
claim is not verified and checked in user_oidc
. But we want to have a situation in NC+OP integration where the services knows that the token is intended only for it to make requests.
Is the audience supposed to always be the Oidc client ID?
If so, then we can validate the audience and this means only tokens obtained by OP with the same Oidc client than NC could be used to make requests against NC.
Hey @julien-nc, AFAIK Keycloak's token endpoint allows replacing one token for another. So, if OP has one access token with the OP client as audience it, then OP can request a new token with it to get another access token with the desired audience, the Nextcloud client. For that to work Keycloak's realm needs to have set policies that allow this. The Keycloak docs explain that. See Keycloak's docs (paragraph 7) on token exchange https://www.keycloak.org/docs/latest/securing_apps/index.html#_token-exchange
If you think it from the other way around: if you don't have audience awareness during authorisation you could (mis)use the same token for requests in the other direction. Without an audience check any Keycloak access token from a client within the same realm will authorize in Nextcloud, even though it was originally given to a completely different client, e. g. some untrustworthy service that you would only give little permissions/scopes within Keycloak.
Ok then I guess we can add audience check in the bearer token validation. This would be the same check as when getting the login token, we would check the audience is the Oidc client ID.
Let's make this check optional and enable by default. Wdyt?
@julien-nc Sounds great! Thank you!