Okta React Native + JWT Verifier - Service unable to Verify Access Tokens - Error while resolving signing key for kid

Hi,

We are trying to utilize Okta to authenticate users (not company emloyees using internal systems, but end-users) of a mobile app written with React Native. After a successful signin, the app shall obtain an access token to be able to access our backend services, which will in turn verify the token using Okta JWT Verifier for Node.js. To allow the signin from our app, we try to use @okta/okta-react-native.

Now we are able to obtain access-, id- and refresh-tokens in our app, but our backend is unable to verify the access tokens sent from our App, giving error Code: “Error while resolving signing key for kid {kid}”.

Having seen the recommendations given in a similar post on this forum, we are unsure wether this error is a result of misconfiguration on our side, or we need an “api access management license” for our use case, which we assume shouldnt be the case when Okta is promoting “1000 monthly active users for free” ( https://developer.okta.com/pricing/ ).

Steps we have taken so far:

1) we have signed up for a developer account, signed into our organizations admin panel at https://dev-{ID}-admin.okta.com

2) created a client-application of type mobile/native, allowed grant types “authorization code” and “refresh token” for this client and ticked the recommended “proof key for code exchange” (PKCE) as client authentication mechanism over using a client secret.

3) created an additional authorization Server within the API/Authorization Servers Tab, thinking that it was required to use a “custom authorization server” instead of the default one in order to verify the issued tokens in our own backend.

4) Installed okta-react-native to our codebase and created an oktaAuthClient using a configuration as follows:

clientId: “{Client Id of our mobile application}”,
redirectUri: “com.{ourAppName}:/callback”,
endSessionRedirectUri: “com.{ourAppName}:/endSession”,
discoveryUri:
“https://dev-{Our Accounts Org. ID}.okta.com/oauth2/{Our Custom Auth Servers ID}/.well-known/openid-configuration”,
scopes: [“openid”, “profile”, “offline_access”],
requireHardwareBackedKeyStore: false // Since testing on a virtual device.

5) Installed OktaJWTVerifier for Node.js in our Nest.JS based Backend, Registering it as a middleware to protect our routes and calling jwtVerifier.Verify() with the following configuration:

{ issuer: ‘https://dev-{Our Okta Org ID}.okta.com/oauth2/{Our Custom Auth Server ID}’,
clientId: ‘{Client ID of our mobile application}’,
scopes: ‘[“openid”, “profile”, “offline_access”]’,
assertClaims: { aud: ‘{Client ID of our mobile Application}’ } }

6) Called https://dev-{Our Org. ID}.okta.com/oauth2/{Our Custom Auth Server ID}/v1/keys , seeing that the key-id (“kid”) it replies is not matching the kid in the access_tokens were sending from the mobile application.

Any heads-up on where we went down the wrong path would be greatly appreciated.
Kind regards,

Hi @TobiGe

Okta has two types of authorization servers:

  • Okta authorization servers (available on all Okta tenants)
  • custom authorization servers created through API Access Management feature (free for developer and preview tenants, paid for production tenants)

The error Error while resolving signing key for kid {kid} occurs usually when:

  • you are trying to verify access tokens against the Okta authorization server (which does not return the signing keys for them due to RFC restrictions)
  • you are generating the access tokens on an authorization server and verify then against a different authorization server

Please check that in both React Native app and Node.js app you have the same issuer (“discoveryUri” in case of React Native) and it’s set to something like “https://dev-123456.okta.com/oauth2/default” or “https://dev-123456.okta.com/oauth2/ausxxxxxxxxxxxxxxx”. The issuer of the authorization server can be found under Admin >> (Security)* >> API >> Authorization Servers >> “Issuer URI” column.

*available when using the Classic UI administrative interface

Hi @dragos

I made sure the “issuer” configured for the jwt-verifier and “discovery-uri” for the react-native SDK are pointing towards the default-custom-auth-server under “https://dev-{someID}.okta.com/oauth2/default”. Yet the “iss” field of the tokens returned to my react native app still yield “https://dev-{someId}.okta.com” (note the missing “/oauth2/default”), which tells me I am trying to fetch tokens from the “okta authorization servers” instead of my “custom authorization server”.

When generating a token preview via API > Authorization servers > default option > token preview, the generated token does feature “https://dev-{someId}.okta.com/oauth2/default”, which I assume confirms the above assumption.

However, I am fetching the tokens using https://www.npmjs.com/package/@okta/okta-react-native, which doesnt allow me to explicitly set an issuer and seems to fetch tokens from the “okta authorization servers” no matter what I set the “discovery URI” to. Am I using the wrong package and should be using a generic OIDC Client instead?

EDIT: Nevermind, the problem was related to a cached instance of okta-react-native that didnt get reset on reload of our dev-environment, thus we were constantly refreshing a login on the okta-org auth server, instead of starting a new attempt onto newly configured custom auth servers. After also implementing logout and clearing device storage, things seem to work as expected.

Thank you for your time and the clear explanation above :slight_smile: