mvertopoulos / vue-msal

Vue plugin for using Microsoft Authentication Library (MSAL)
MIT License
123 stars 66 forks source link

Get access token for API? #20

Open dochoss opened 4 years ago

dochoss commented 4 years ago

Apologies if this doesn't fit here, but I'm having a hell of a time figuring out how to use this to get a token to call an API. The API is hosted in the same Azure AD tenant as my web app that's using vue-msal. I've been able to authenticate properly but the token audience always comes back as the GUID for MS Graph (00000003-0000-0000-c000-000000000000). All the other info in the token seems correct, but when I pass the access_token as a bearer token to the API, I get a 401 Unauthorized response.

Here's the config I'm using.

Vue.use(msal, {
  auth: {
    clientId: '62...fa', // my API client id
    tenantId: 'f1...ca', // my AD tenant id
    requireAuthOnInitialize: true
  }
});

I'm very inexperienced at auth in general, so I may even be asking the wrong questions. Anyone able to steer me in the right direction here?

baSSiLL commented 4 years ago

I suppose you need to use scopes to specify an API of interest. By default vuew-msal sets scopes: ["user.read"] which requests access to MS Graph for reading user data from AD hence the audience value you see in returned token. Actually I only worked with AD B2C so I can say about it. But I suppose it's very similar to regular AD regarding the process of acquiring access tokens. If your app and API share the same client ID (API serves solely as a backend for an app) then you can simply put this client ID to scopes:

auth: {
  ...
  scopes: ['62...fa'] // your client ID
}

Otherwise, an API should have published scopes identified by URLs and an app should be granted some of these scopes in AD settings. Then you specify needed scope(s) in the scopes parameter.

auth: {
  ...
  scopes: ['https://contoso.onmicrosoft.com/api/read'] // URL(s) of API scope(s) access to which is requested
}

Hope this helps.

dochoss commented 4 years ago

This did the trick. I got a token with this call:

await msal.acquireToken({ scopes: ['https://myFunctionApp.azurewebsites.net/user_impersonation'] });

Thank you very much!

Now I'm in a weird spot where I want to be able to call MS Graph AND my API. But during the acquireToken method, it sets the msal object's accessToken to whatever is returned. I find that sometimes the calls' timing is weird and they won't be set as expected during the proper calls (e.g. an API call will happen after the Graph call and have the wrong token). Is there a way to store multiple tokens and use the appropriate one per request?

baSSiLL commented 4 years ago

Sorry, cannot help you further :( As I see from the code, vue-msal only stores one "current" access token which is used for MS Graph calls. Probably, you'll be able to use several instances of vue-msal in the same app for working with different APIs/scopes.

dochoss commented 4 years ago

No worries, I understand. I actually wound up implementing MSAL myself to have easier access to the MSAL methods. This project helped me understand it a lot better, though!