2
votes

We are using Azure active directory Oauth code flow to authenticate the user. We got the access_token, id_token and refresh_token using code(got it on redirect URL). We are using id_token to authorization each request after successful authentication and we can verify JWT using the public key which we got from /discovery/v2.0/keys api.

Now, JWT will expire after 1 hour. so we need to refresh this id_token.

I am refreshing id_token using below cURL

 curl --request POST \
  --url https://login.microsoftonline.com/{tenant_id}/oauth2/token \
  --header 'Content-Type: application/x-www-form-urlencoded' \
  --data 'client_id=client%20id&refresh_token=refesh%20token%20&grant_type=refresh_token&client_secret=client_secret&scope=openid

In the response of this API, we got the access_token, refresh_token, id_token, but if you observe id_token, it does not contain JWT signature (the third part of JWT), without signature we can not verify JWT

sample response of refresh token API

We can not find any document reference why id_token is not having a signature part. Is there any other way to refresh id_token? Is there any workaround if id_token can not be refreshed?

1

1 Answers

1
votes

In some cases an Id token may be returned without a signature, especially if it is acquired through a back-channel with a client secret. You already are getting the token through an encrypted channel, from the authority. If someone was able to inject something there, they would be able to direct your app's requests for OpenID metadata as well, replacing the signing keys your app expects. Thus the signature would not add much value here.

In addition, you won't send the Id token to any API as Id tokens should not be used for authorization. That's what access tokens are for :)

The OpenID Connect spec has this to say: https://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation

If the ID Token is received via direct communication between the Client and the Token Endpoint (which it is in this flow), the TLS server validation MAY be used to validate the issuer in place of checking the token signature. The Client MUST validate the signature of all other ID Tokens according to JWS [JWS] using the algorithm specified in the JWT alg Header Parameter. The Client MUST use the keys provided by the Issuer.

But then, interestingly mentions this as well: https://openid.net/specs/openid-connect-core-1_0.html#IDToken

ID Tokens MUST be signed using JWS and optionally both signed and then encrypted using JWS and JWE respectively, thereby providing authentication, integrity, non-repudiation, and optionally, confidentiality, per Section 16.14. If the ID Token is encrypted, it MUST be signed then encrypted, with the result being a Nested JWT, as defined in [JWT]. ID Tokens MUST NOT use none as the alg value unless the Response Type used returns no ID Token from the Authorization Endpoint (such as when using the Authorization Code Flow) and the Client explicitly requested the use of none at Registration time.

So.. it could be that Azure AD is not compliant with spec?

EDIT: The v1 endpoint of Azure AD is not compliant in this regard. The newer v2 endpoint is fully OpenID Connect compliant.