10
votes

I receive two JWTs: an OpenID Connect ID token (id_token) and an Access Token (access_token). The situation with OpenID is more or less clear - I can validate it using a JWKS Endpoint: https://smth.com/JWKS.

as in example (https://bitbucket.org/b_c/jose4j/wiki/JWT%20Examples):

HttpsJwks httpsJkws = new HttpsJwks("https://smth.com/JWKS");
HttpsJwksVerificationKeyResolver httpsJwksKeyResolver = new HttpsJwksVerificationKeyResolver(httpsJkws);
jwtConsumer = new JwtConsumerBuilder()
    .setVerificationKeyResolver(httpsJwksKeyResolver)
    .setExpectedAudience(...)
    .setExpectedIssuer(...)
    .build();

The question is how to proceed with the Access Token. I can extract from it the userId and userDetails, but I guess I need also to validate it?

If I try to validate the Access Token the same as for the ID Token, I am getting this error:

UnresolvableKeyException: Unable to find a suitable verification key for JWS w/ header {"alg" : "RS256", "kid":"1"}

And indeed there is no key for "kid" : "1", Also this value "1" seems kind of strange?

Am I doing something totally wrong?

1
What's the content of smth.com/JWKS? smth.com doesn't resolve for me. - Brian Campbell
The full exception message should also show the content from that JWKS endpoint. Without seeing the JWKS I can't say exactly what's going on but basically what is happening is the JWT was signed with RSA and a key id header with value "1" was included, which should point to the appropriate verification key in the JWKS (visual example slideshare.net/briandavidcampbell/i-left-my-jwt-in-san-jose/30). It would appear that there's no RSA key with kid=1 at that JWKS endpoint. - Brian Campbell
Thanks for response, I changed question. Yes there is no key for kid=1, also value '1' seems strange compared to OpenID, where I get some real kid, like 'dp1kr' and it changes over time. If you faced this kind of authentication and can give me a hint - if both tokens should be proceeded in same way or not? - Petr Averyanov

1 Answers

5
votes

It sounds like you are implementing the role of OpenID Connect client or Relying Party. The two tokens, ID token and access token, serve different purposes and should be handled differently by the client. The ID token is intended for the client and enables authentication of the end-user at the client. The client must validate the ID token (verify the signature and validate claims like exp and aud, etc.) before allowing the end-user in. The access token, however, is for the client to use to access resources or APIs but is not directly intended for the client to consume or validate. The access token is opaque to the client and the client shouldn't care or know about its details. In fact, access tokens aren't always JWTs. In OpenID Connect, the access token is used to call the user info endpoint (with the HTTP header, Authorization: Bearer [access token]) to get more claims/info about the end-user.

The value of "1" for the kid is totally legal but it is referring to a key that the AS/OP and the user info endpoint know about somehow. It is not a key at the OpenID Connect JWKS endpoint. "1" isn't a key that the client needs to know about because the client isn't supposed to directly verify the access token.