3

I would like some clarification on how to use ID tokens and access tokens in an implicit grant flow. I have an Angular SPA using MSAL.js for Angular package and a Web API. The API does NOT call any external services, like MSFT Graph. The back end uses role claims from JWT to establish RBAC authorization to our API functionality only.

This doc says: https://learn.microsoft.com/en-us/azure/active-directory/develop/id-tokens

id_tokens are sent to the client application as part of an OpenID Connect flow. They can be sent along side or instead of an access token, and are used by the client to authenticate the user.

ID Tokens should be used to validate that a user is who they claim to be and get additional useful information about them - it shouldn't be used for authorization in place of an access token.

This doc shows an authentication flow where a web API is called with an ID token instead of an access token: https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-implicit-grant-flow

This sample code sends ID token too (calling own Web API sample): https://github.com/Azure-Samples/active-directory-javascript-singlepageapp-dotnet-webapi-v2

The sample back end validates ID token audience against Client ID of the app that issued it.

Given our API is the only consumer of tokens, should we use ID tokens or access tokens?

Community
  • 1
  • 1
oskarm
  • 123
  • 3
  • 8
  • In the article and the sample you link to, could you point to the specific section (or quote), or file and line where the ID token is being used to call the web API? – Philippe Signoret Oct 20 '19 at 09:15
  • @PhilippeSignoret I ran the sample and inspected the token. The sample tells you to validate token audience by setting it to client ID of the app. Only ID tokens have aud claim set to client ID of the app. In the article diagram it shows passing the token to Web API after MSAL gets it from the fragment. By default MSAL will only get an ID token and send it to the backend. – oskarm Oct 21 '19 at 08:40
  • The `aud` claim of the access token will have the client ID of your *API* (i.e. the app ID of the app registration for the API). This will only be the app ID of the client when you're using the same app registration for both the frontend and backend. In all cases, the token your frontend is sending to the API is the access token, not the ID token. MSAL does not make API requests to your backend. When calling any of the `acquireToken...` functions, MSAL will return an access token to he used by the application's code when calling the backend. – Philippe Signoret Oct 21 '19 at 13:16
  • If you could point out which files/lines suggest what you describe, we could clarify that part. – Philippe Signoret Oct 21 '19 at 13:17
  • @PhilippeSignoret todoListCtrl.js line 5 defines the scope as Client ID. This is then used on line 94 to request a token. This is also what we do. But the token you get from this call is indistinguishable from an ID token. – oskarm Oct 21 '19 at 16:33
  • @PhilippeSignoret The token retrieved by this sample in hash fragment (#id_token=ey...) is exactly the same as the Bearer token attached to /api/todoList API call in Authorization header. This is what I mean when I say it's sending ID token to the back end. – oskarm Oct 21 '19 at 16:58
  • If your API is the same app registration as the client, then it's normal that they seem similar, but they're not identical. The access token will contain `scp`, `azp` and `azpacr` claims. In the sample, the token used to call the API is the access token, not the ID token. – Philippe Signoret Oct 21 '19 at 20:09
  • @PhilippeSignoret That is not correct. Inspecting token claims of the Bearer token attached to todoList API call, it does not contain any of the claims you mentioned. – oskarm Oct 22 '19 at 09:27
  • 3
    I'm sorry, you're completely right about the sample: it *is* sending an ID token to the API. (What I said about access vs. ID tokens is accurate, what I said about what the sample is doing is not accurate.) I will dig into this to understand why the sample is sending ID token (i.e. is it the sample or is it MSAL?) and report back. In any case, the general answer to your question is that clients are expected to send access tokens, not ID tokens, to the API. – Philippe Signoret Oct 23 '19 at 11:16

2 Answers2

0

Generally speaking, when securing your API with the Microsoft Identity platform, clients should be using the access token when making API requests, not the ID token.

Philippe Signoret
  • 13,299
  • 1
  • 40
  • 58
0

check this part enter image description here

It first calls acquireTokenSlient, which gets a token from the cache if available if not it calls acquireTokenPopUp which will get an acces token for the specific scope, I am not sure if it would open up a popup window or will get a token in the background with hidden iframe. But it would fetch an access token for sure. API can never be accessed with ID token.

check https://learn.microsoft.com/bs-latn-ba/azure/active-directory/develop/scenario-spa-acquire-token for more clarification

biswpo
  • 771
  • 7
  • 23
  • The link you gave is not the same as my scenario, because I don't request user.read scope. – oskarm Oct 21 '19 at 16:31
  • Irrespective of that the flow should be same, you must be requesting it against scope of your API in or the resource ID of the App depending on whether you use ADAL or MSAL – biswpo Oct 21 '19 at 16:36