Closed svvac closed 4 years ago
These validations aren’t strict, thats how the spec is written, what google says in their docs is kinda irrelevant. What would you propose gets loosened?
After reading relevant parts of the spec, it appears that the check in question is indeed mandated :
2 — ID token :
azp
: OPTIONAL. Authorized party - the party to which the ID Token was issued. If present, it MUST contain the OAuth 2.0 Client ID of this party. This Claim is only needed when the ID Token has a single audience value and that audience is different than the authorized party. It MAY be included even when the authorized party is the same as the sole audience. Theazp
value is a case sensitive string containing a StringOrURI value.3.1.3.7 — ID token validation : 5. If an
azp
(authorized party) Claim is present, the Client SHOULD verify that itsclient_id
is the Claim Value.
However, this raises the question : if multiple audiences can be provided, how are the others (the ones that are not azp
) supposed to validate the ID token if the assertion aud === azp === client_id
must hold?
The spec indeed considers cases where this is not the case, for instance:
3.1.3.7 — ID token validation : 8. If the JWT
alg
Header Parameter uses a MAC based algorithm such as HS256, HS384, or HS512, the octets of the UTF-8 representation of theclient_secret
corresponding to theclient_id
contained in theaud
(audience) Claim are used as the key to validate the signature. For MAC based algorithms, the behavior is unspecified if theaud
is multi-valued or if anazp
value is present that is different than theaud
value.
This suggests that it should be possible to handle such tokens and consider them valid.
What would you propose gets loosened?
I was thinking of providing a way to tell Client
a list of authorized 3rd-party client_id
that should be accepted for azp
for the cases where the authorized party is not the audience, or disable the check altogether. Of course, the default should still be to enforce client_id
as it is the most common case by far.
the idea : svvac/node-openid-client@7c781d2
That won’t fly. That metadata object is only for registered iana parameters and i don’t intend to mix em up with proprietary configuration.
I get the gist tho, when i have the time i’ll take a look at solving this.
I'd like to help, if you have pointers for your preferred way of passing this kind of configuration.
I’ll be happy to give you pointers for this when i’m done with my move next week.
@svvac
we're looking to add an additional parameter (an object so that we can add more of these in the future) to these methods
new issuer.Client(metadata[, jwks, [other]])
issuer.fromUri(uri, token[, jwks, [other]])
The following already has a last argument for these "options"
issuer.Client.register(metadata[, other])
we should also rename "properties" to "metadata" in the codeIt boils down to extending the constructor and then just passing the extra from the other methods.
Was the authorized_thrid_parties
option name alright? Or maybe you'd prefer camelCase?
camelCase for these "extras" is better, the only snake_case present is for IANA registered parameters.
And is the boolean value option necessary? To accept all? Why?
It helps validating ID tokens in the case where you can't really know in advance all 3rd-party client IDs that might initiate the OIDC auth flow for logging into your service.
In the case of Google's android app login flow, it can be useful if you wish to be able to roll out new apps without having to redeploy the server component. The responsibility of validating 3rd-party client IDs is thus delegated to the issuer. For instance, Google only allows this if the authorized presenter is in the same « project » as the target audience.
I'd prefer to leave the "accept all" option out. All claims need to be validated to be expected values. "anything" isn't really validating.
I see your point, though I'd like to point out that it forces unnecessary coupling between the client configuration and the issuer policy (i.e. is this client allowed to request login for that client)
Currently, JWT validation throws if the authorized presenter (
azp
field) is not equal to theclient_id
(see here).However, according to Google's OIDC docs, it is specifically different from the
aud
(Audience) field if present (emphasis mine) :More specifically, it happens in Android mobile app authentication flow :
aud
set to the server's client_id andazp
to the app's client IDAFAICT, this auth flow is currently not possible with node-openid-client