microsoft-authentication-library-for-js: Unable to use acquireTokenSilent() method for Live Accounts via Azure B2C

It seems that the Out of Box experience for using MS Live as a Identity Provider isn’t working properly. I’m able to log in correctly. However, the acquireTokenSilent() method forces a redirect in my Angular application. The problem is, MSAL 0.1.5 doesn’t set a ‘msal.state.acquireToken’ entry to the Sesson or Local storage cache, thus causing the URL hash and subsequently the newly acquired access token to be systematically disregarded. I have included a really nasty hack that seems to address this issue from the client’s perspective, but I’d image there must be a much better solution that can be implemented from within the MSAL code base:

const hackToSupportLive = 'Renew token Expected state:';
const storage = new Storage('localStorage');
        const logger = new Msal.Logger(
            (level: Msal.LogLevel, message: string, containsPii: boolean) => {
                const index = message.indexOf(AuthenticationService.hackToSupportLive);
                if (index > -1) {
                    const neededState = message.substring(index + 28);
                    storage.setItem(Constants.stateAcquireToken, neededState.trim());
                }
            },
            { level: Msal.LogLevel.Verbose, piiLoggingEnabled: true });

        this.authClient$ = new Msal.UserAgentApplication(
            this.appConfig$.clientID,
            this.appConfig$.authority,
            (errorDesc, token, error, tokenType) => {
                if (!error && token) {
                    console.log(`Token: ${token} - ${tokenType}`);
                } else {
                    console.log(`Error: ${error} - ${errorDesc}`);
                }
            },
            { cacheLocation: 'localStorage', loadFrameTimeout: 20000, navigateToLoginRequestUrl: false, logger: logger });

My questions are

  1. What’s causing MSAL to force a redirect whenever an attempt to acquire an access token from a Live account?
  2. Why doesn’t this occur whenever other 3rd party identification providers are used (i.e. Facebook)?
  3. Though the acquireTokenSilent apparently sets a new randomized State ID, why is it not being stored in the Local or Session storage areas so that it can be properly processed during the next callback?

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 5
  • Comments: 15 (5 by maintainers)

Most upvoted comments

Hi folks. The problem is not MSAL.js but https://login.live.com/oauth20_authorize.srf. Here is what I found out when I was debugging the entire acquireTokenSilent process:

When the iframe (msalRenewFrame…) tries to authenticate at https://login.live.com/oauth20_authorize.srf, https://login.live.com/oauth20_authorize.srf attempts to ‘framebust’ (navigate the parent of the iframe which is the main site). Chrome shows this warning:

image Frame with URL 'https://login.live.com/oauth20_authorize.srf?client_id=… attempted to navigate its top-level window with URL 'http://localhost:4200/#/dashboard'. Navigating the top-level window from a cross-origin iframe will soon require that the iframe has received a user gesture. See https://www.chromestatus.com/features/5851021045661696. DoSubmit @ oauth20_authorize… onload @ oauth20_authorize…

This causes the main site to redirect, which turns acquireTokenSilent into acquireTokenBoisterous. Just kidding.

I tried to sandbox the msalRenewFrame… with ifr.setAttribute("sandbox", "allow-forms allow-pointer-lock allow-popups allow-same-origin allow-scripts") according to https://www.w3schools.com/tags/att_iframe_sandbox.asp. Now the main site does not redirect away, but now Chrome shows an error:

image Unsafe JavaScript attempt to initiate navigation for frame with URL 'http://localhost:4200/#/dashboard' from frame with URL 'https://login.live.com/oauth20_authorize.srf?client_id=… The frame attempting navigation of the top-level window is sandboxed, but the flag of 'allow-top-navigation' or 'allow-top-navigation-by-user-activation' is not set.

I assume this framebusting happens for compatibility reasons (we all know how redirect heavy logging in into Microsoft services is). I am afraid this is no easy fix. But Chrome will break it soon anyway so maybe the team behind https://login.live.com/oauth20_authorize.srf is already on it. Until then Azure AD B2C in combination with Live Accounts and MSAL.js is broken and cannot be used.

I also posted this on StackOverflow: https://stackoverflow.com/questions/49831045/msal-js-acquiretokensilent-on-azure-ad-b2c-with-microsoft-account-login-live-co

So, is there any word on getting this resolved?

@navyasric, what can we do to workaround this issue ? It is a blocking issue since we cannot get access tokens for all MS accounts from MSAL.js. (We also have a different issue for Twitter accounts #349) The README reads

This library is suitable for use in a production environment.

This (blocking) issue is 7 months old ! The #349 is 3-4 months old. Please do something…

Is this issue resolved? I am trying to renew idtoken before it expires by calling acquiretokensilent, I get a new token but it disregards it and still uses the old idtoken and as soon as idtoken expires it redirects me back to my login page. is there any resolution to it? I am using the latest msal library. I don’t want the users to login again after every one hour. How do I renew the session?

any updates? still encountering this issue

I’m seeing exactly the same issue so it’s good to see that the bug tag has been applied. In my scenario login to my website works for MS Accounts and Google accounts however if you then hit a page which makes a call to an API secured using B2C the above issue occurs.

My error on Google accounts is slightly different but i’ll include it below in-case the two are somehow linked.

Refused to display 'https://accounts.google.com/o/oauth2/auth.....' in a frame because it set 'X-Frame-Options' to 'sameorigin'.

My understanding is that all of the tokens are issues from B2C and not from the ID providers so I’m unsure why any redirect is happening off to login.live.com or accounts.google.com when the token is no more than a few seconds old.

I’m using the latest version of msal-angular which at the time of writing is 0.1.2.