kid not matching on OAuth 2.0 flow

2.4k views Asked by At

I'm using Okta for identity management. As the client in authorization flow, I send an authorize request to Okta. This works successfully, and I get a JWT payload. I want to verify the JWT signature, so I make another call to Okta in order to fetch the keys. However, the key ids (kids) do not match and verification fails.

Initial authorize request:

https://{{site}}.okta.com/oauth2/v1/authorize
  ?scope=openid
  &response_type=id_token
  &client_id={{client_id}}
  &redirect_uri={{redirect_url}}
  &nonce=4euiv0v52at3la15e7qlu1mt43
  &state=7c92bqulrmdk2jk0ro9rd3mf5j

Response is a 403, redirecting me to:

{{redirect_url}}/id_token={{id_token}}

The header of the id_token is decoded into:

{
  "alg": "RS256",
  "kid": "2YKtkekCjCRWN0YqGsjUrNwIQaxGg5ahfHW0_fK8t64"
}

So far so good. I know that the authorization has succeeded. Time to validate the JWT.

However, when this is followed up with:

https://{{site}}.okta.com/oauth2/v1/keys

Or

https://{{site}}.okta.com/oauth2/v1/keys?clientId={{client_id}}

(they both return the same response), I get back this:

{
  "keys": [
    {
      "alg": "RS256",
      "e": "AQAB",
      "n": "gv1rI9A7mrOoViJZTzUfiZl7YdEzLEofvRoVbXCgeW7aOmoKcAkWGHvqNRGoFgi8auV5b_TSgTXKq_TV1fz643hpAtba3V0Uw2lXchTbqXpmVRYXI1t4FIwRMXLe4Q-kcvp9la21e3D1lszjdPbFNX5GLAhrCW0Thu2HYbTLg6TbDTMaiQCMo15hek0JgZqRGzCkt9kINnwPVLXV_bkSh_fHWo_6G1L0MKYYQcgE6zvPlULLek98-yZ6Nlg6nJUY9nHn0qjhzqqq-bz_Vin8qi3Bt7SjUKwk7HbaugM84AEgDxYE5JgsaALIl5SgIc3GgFEc69qKWymoD-w1a8f1HQ",
      "kid": "SOxFkBSLWefjlZoDI49Hk0nqlYtC28cjhTlVAYEzAxs",
      "kty": "RSA",
      "use": "sig"
    }
  ]
}

Where the kid does not match what I received in the original response.

Where is my mistake?

2

There are 2 answers

0
Magua On BEST ANSWER

The problem was that this account was setup with pinned, not rotating keys. oauth2/v1/keys requires the client id to be passed in as a parameter if you are setup with pinned keys; the correct parameter name is "client_id", not "clientId." This results in the expected output.

8
Matt Raible On

You need to create an authorization server and use it as the endpoint, for example:

https://{{site}}.okta.com/oauth2/{authorizationServerId}/v1/authorize

You should also be able to use the default one:

https://{{site}}.okta.com/oauth2/default/v1/authorize

Note that this is different than the route you were using (which does not specify an authorization server):

https://{{site}}.okta.com/oauth2/v1/authorize

You should specify an authorization server in your case (like example 1 and 2 above), for both OAuth 2.0 and OpenID Connect.