Search code examples
ember.jsoauthsingle-page-applicationazure-ad-msalmsal.js

Should I try an MSAL getTokenSilent() before any request for a protected resource?


I'm integrated the MSAL JS library with an EmberJS SPA. In the current implementation I have a getTokenSilent() call before a user requests a "protected" resource. This means that after a user Authenticates, they collect a new access token before the resource is requested.

Is this intended? Aside from an extra network request I don't see many drawbacks. It should allow for very short-lived access tokens and allow MSAL to check that a user is still in a "valid" state (ie they haven't had their account disabled) since they logged in.

I'm very new to OAUTH and MSAL so some guidance would be great.


Solution

  • The pattern is indeed that one. Before making a request to your API, you should call the acquireTokenSilent() function to see if you can retrieve a suitable token silently. That function will do the following:

    • Checks the cache for a valid token and returns it
    • If there is no valid token, the function will try to acquire a new one with a refresh token

    If both options fails, there will be an InteractionRequiredAuthError thrown, which you need to catch and trigger an acquireTokenRedirect() (or acquireTokenPopup()).

    You can see this vanilla JS MSAL sample: https://github.com/Azure-Samples/ms-identity-javascript-tutorial/tree/main/3-Authorization-II/1-call-api

    Check the getTokenRedirect() function:

    function getTokenRedirect(request) {
    
        /**
        * See here for more info on account retrieval: 
        * https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-common/docs/Accounts.md
        */
    
       request.account = myMSALObj.getAccountByUsername(username);
       
       return myMSALObj.acquireTokenSilent(request)
           .catch(error => {
               console.error(error);
               console.warn("silent token acquisition fails. acquiring token using popup");
               if (error instanceof msal.InteractionRequiredAuthError) {
                   // fallback to interaction when silent call fails
                   return myMSALObj.acquireTokenRedirect(request);
               } else {
                   console.error(error);   
               }
       });
    }