YtSh91
YtSh91

Reputation: 111

Invalid signature while validating Azure ad access token

I am getting invalid signature while using jwt.io to validate my azure ad access token (will shift to scala code after the manual checking).

I am using curl to generate the access token:

curl -s -X POST https://login.microsoftonline.com/<tenant id>/oauth2/token -d grant_type=password -d username=$username -d password=$pass  -d resource=$resID -d client_id=$id -d client_secret=$key

While it is giving me the access token, the response doesnt contain the "Id_token". Not sure why.

I am wrapping the public key from https://login.microsoftonline.com/common/discovery/keys with BEGIN and END certificate. (as mentioned in https://nicksnettravels.builttoroam.com/post/2017/01/24/Verifying-Azure-Active-Directory-JWT-Tokens.aspx)

I am not sure what else is missing.

The decoded header is as follows:

{
  "typ": "JWT",
  "alg": "RS256",
  "x5t": "9FXDpbfMFT2SvQuXh846YTwEIBw",
  "kid": "9FXDpbfMFT2SvQuXh846YTwEIBw"
}

Upvotes: 1

Views: 9983

Answers (1)

Philippe Signoret
Philippe Signoret

Reputation: 14336

Warning: You are invoking a flow which is unsupported, and will be removed in the near future.

The Resource Owner Password Credentials Grant flow (grant_type=password) is not supported in Azure AD with confidential clients (i.e. web app/web API, where there exists a client_secret). If you are confident your scenario requires the Resource Owner flow (very few scenarios actually warrant the risks introduced by this flow), then you should be invoking it with a client_id registered for a native client app (a public client). Alternatively, you should be invoking an interactive sign-in (if you are signing in actual human users), or pursuing the Client Credentials Grant flow (if this is a daemon/unattended service).

You are not getting an ID Token because the flow you've invoked (the OAuth 2.0 Resource Owner Password Credentials Grant flow), does not define any concept of an ID Token, or an id_token response. In other words: you haven't asked for one.

If you add scope=openid to your Authorization Request, you'll be hinting to Azure AD that you're more or less interested in knowing stuff about the person who signed in, and you'll get an unsigned OpenID Connect ID Token in the response.

To https://jwt.io to verify the claims:

  1. Ensure this is a token intended for you. (i.e. don't expect to be able to decode and verify a token that was not intended for you (where "you" are the resource in the Authorization Request, and the aud in the token claims).
  2. Ensure you've selected the correct signing algorithm (RS256).
  3. Ensure you're checking against the key with which the token was signed (use the kid header value from the JWT as a hint).
  4. Ensure the certificate ends in -----END CERTIFICATE----- (I've found jwt.io doesn't care too much about how it starts.
  5. Double-check your copy-pasting, it's easy to accidentally pick up extra characters.

Upvotes: 1

Related Questions