[ ] Regression (a behavior that used to work and stopped working in a new release)
[x] Bug report
[ ] Performance issue
[ ] Feature request
[ ] Documentation issue or request
[ ] Other... Please describe:
Library version: 1.2.0
Hi, I updated library from 1.1.2 to 1.2.0 and I got error "Token calls are blocked in hidden iframes". I'm not using app in the iframe (it's just React app in the browser). Method "acquireTokenSilent" causes such error. I have very easy setup (redirect + acquireTokenSilent) from this sample https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-core/README.md#3-get-an-access-token-to-call-an-api. Authentication works fine but I'm getting this error is in the console.
My configuration:
const msalConfig: msal.Configuration = {
auth: {
clientId: '',
authority: '',
redirectUri: '',
navigateToLoginRequestUrl: false,
},
cache: {
cacheLocation: 'localStorage',
storeAuthStateInCookie: true,
},
};
There is no such error in the browser console.
As part of the OAuth Implicit flow, our library uses hidden iframes to acquire access tokens. When a token has been acquired, AAD will load your redirect URI inside this hidden iframe, with the access token included in the url (as the hash). This error is thrown when we detect that your application is calling acquireTokenSilent on page load inside of that iframe, in order to prevent any bad side effects as a result (e.g. endlessly trying to acquire tokens).
If you would like to suppress this error, do not call acquireTokenSilent on page load when there is hash in the url and your app is inside an iframe.
You can also now set your redirect uri for acquireTokenSilent calls to a page which does not run MSAL (pass redirectUri into the acquireTokenSilent options object).
You should also have a .catch block on all acquireTokenSilent calls, generally speaking (I'm guessing you either don't have a catch block, or are rethrowing all errors? If the later, you should inspect each error and handle appropriately).
@sameerag I think it would be good to expose an API to make it easy for apps to detect this.
@jasonnutter Okay, but is it possible to retrieve token from the hash in the url (is there any public method for that?)? Then I wouldn't have to call method acquireTokenSilent.
@tszymanik acquireTokenSilent does that for you, by opening the hidden iframe with the appropriate url to AAD, then parsing, storing, and returning to you the hash in the url when AAD redirects the hidden iframe back to your redirect URI.
I also get this on Macintosh Opera browser
block_token_requests
ClientAuthError: Token calls are blocked in hidden iframes
@flieks See my answer above about how to mitigate this error.
@jasonnutter i read it but dont fully understand it. My app isnt running inside an iframe..
i have this code (i just added the if(location.href.indexOf("#")) on your request)
``` const acquireToken = (request, redirect) => {
return msalApp.acquireTokenSilent(request).catch(error => {
// Call acquireTokenPopup (popup window) in case of acquireTokenSilent failure
// due to consent or interaction required ONLY
console.log(error.errorCode)
if(error.errorCode == "block_token_requests") {
if(location.href.indexOf("#") > -1) {
window.location.href = "https://mvp.salesnote.be"
}
}
if (requiresInteraction(error.errorCode)) {
console.log('will do a redirect')
setInteractionNeeded(true)
return redirect
? msalApp.acquireTokenRedirect(request)
: msalApp.acquireTokenPopup(request);
} else {
console.error('Non-interactive error:', error.errorCode)
}
});
}
```
@flieks MSAL uses hidden iframes to acquire tokens. How this works is MSAL loads an iframe with the url set to login.microsoftonline.com (or whatever your authority is) with the parameters for your specific request. When a token has been acquired, the iframe is redirected back to the url you set for your redirectUri, thus loading your website (briefly) inside an iframe. The page should only load for a brief moment (as we just need to extract the url containing the hash from the iframe), but it can be long enough for parts of your application to load (before the iframe is removed).
The block_token_requests error occurs if we detect that your application is attempting to acquire an access token (e.g. by calling acquireTokenSilent) immediately on page load while the application is loaded inside one of these hidden iframes. The library throws this error to prevent negative side effects from occurring (namely endlessly requesting access tokens).
We generally don't recommend calling acquireTokenSilent on page load, but if you do, one approach to prevent this is to not call acquireTokenSilent on page load in this scenario, or catch the error and let is silently fail.
And as I mentioned, I'll see if we can export some of the helper function from the library that you can use to detect this scenario.
hi @jasonnutter thanks thats very clear and right, i am running acquiteTokenSilent on pageLoad
Wwhat i could do is put window.self !== window.top and if in iframe, delay the acquiteTokenSilent by 10 seconds so that the parent site has time to close the iframe right ?
@flieks In theory that would work, but I would recommend instead just not making the call at all in that scenario.
Same issue here.
Got the error: msal token calls are blocked in hidden iframes, then immediately timeout. any fix for that?
@stoicad See my comment above for background and mitigation.
hi @jasonnutter thanks thats very clear and right, i am running acquiteTokenSilent on pageLoad
Wwhat i could do is put window.self !== window.top and if in iframe, delay the acquiteTokenSilent by 10 seconds so that the parent site has time to close the iframe right ?
This worked like a charm
Most helpful comment
@flieks MSAL uses hidden iframes to acquire tokens. How this works is MSAL loads an iframe with the url set to
login.microsoftonline.com(or whatever your authority is) with the parameters for your specific request. When a token has been acquired, the iframe is redirected back to the url you set for your redirectUri, thus loading your website (briefly) inside an iframe. The page should only load for a brief moment (as we just need to extract the url containing the hash from the iframe), but it can be long enough for parts of your application to load (before the iframe is removed).The
block_token_requestserror occurs if we detect that your application is attempting to acquire an access token (e.g. by callingacquireTokenSilent) immediately on page load while the application is loaded inside one of these hidden iframes. The library throws this error to prevent negative side effects from occurring (namely endlessly requesting access tokens).We generally don't recommend calling
acquireTokenSilenton page load, but if you do, one approach to prevent this is to not callacquireTokenSilenton page load in this scenario, or catch the error and let is silently fail.And as I mentioned, I'll see if we can export some of the helper function from the library that you can use to detect this scenario.