Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Token calls are blocked in hidden iframes #1194

Closed
1 of 5 tasks
toddfsnyder opened this issue Jan 9, 2020 · 15 comments
Closed
1 of 5 tasks

Token calls are blocked in hidden iframes #1194

toddfsnyder opened this issue Jan 9, 2020 · 15 comments
Assignees
Labels
question Customer is asking for a clarification, use case or information.

Comments

@toddfsnyder
Copy link


[ X] Regression (a behavior that used to work and stopped working in a new release)
[ ] Bug report  
[ ] Performance issue
[ ] Feature request
[ ] Documentation issue or request
[ ] Other... Please describe:

Browser:

  • Chrome version 79
  • Firefox version XX
  • IE version XX
  • Edge version XX
  • Safari version XX

Library version


Library version: 1.2

Current behavior

After upgrading to the latest msal.js (1.2) library we are seeing this error when trying to silently retrieve the token for Azure B2C. In msal.js (1.0.2) we do not see this error using the same code.

ERROR:
Could not silently retrieve token from storage. ClientAuthError: Token calls are blocked in hidden iframes

Expected behavior

To be able to retrieve the silently token for Azure B2C without any issues.

Minimal reproduction of the problem with instructions

Single Page App (e.g. Angular) that is directly using the msal.js library to log into Azure B2C
After logging in, a request is made to get the token from Azure B2C to call an external Web API.

Setup Client Application with required B2C Configuration - cache location is localStorage and storeAuthStateInCookie is true.

  this.clientApplication = new Msal.UserAgentApplication(msalConfig);

Call Login

this.clientApplication.loginRedirect(loginRequest);

After the login flow to Azure B2C is complete try to get the silent token

 this.clientApplication.acquireTokenSilent(tokenRequest)
@jasonnutter jasonnutter added the question Customer is asking for a clarification, use case or information. label Jan 9, 2020
@jasonnutter
Copy link
Contributor

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).

@jasonnutter
Copy link
Contributor

Note, this error is mostly informative, and shouldn't prevent you from retrieving a token.

@jasonnutter jasonnutter self-assigned this Jan 9, 2020
@toddfsnyder
Copy link
Author

toddfsnyder commented Jan 9, 2020

Thanks for the prompt response. We do have an try/catch block but were not explicitly logging for this error.

@JosephThomas
Copy link

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).

If there isn't any reason to have the redirect be processed my MSAL, as we would for a login redirect, then what is the point of the hidden iFrame redirecting anywhere? Why doesn't the frame just close after the token has been acquired?

@jasonnutter
Copy link
Contributor

jasonnutter commented Jan 10, 2020

@JosephThomas In the OAuth implicit flow, when iframes are used to acquire tokens, the response is delivered to the library by redirecting the iframe to the provided redirect uri (with the response included in the hash).

In 1.2.0 we changed the way the response is processed, from having the nested instance of MSAL read the url of its iframe (in which it is running) and call into the top-level MSAL instance to pass the response (which required that MSAL be running on the redirect page), to having the top-level instance open the iframe and then monitor it for a redirect back to your app (which means MSAL no longer has to be running on the redirect page), at which point the response in the url is parsed and the iframe is closed. Due to the same-origin policy, MSAL cannot read the url of the iframe to parse the response until the iframe domain matches the domain MSAL is running on, which is why you are required to provide a redirect uri on your domain.

@jasonnutter
Copy link
Contributor

Closing, as no further actionable items at this time.

@nfgallimore
Copy link

nfgallimore commented Mar 26, 2020

I am using MSAL in Angular. I am not calling acquireTokenSilent anywhere in my app explicitly. I am using the MSAL interceptor, and I would expect it to be doing the acquireTokenSilent calls. I am getting around 19-20 of these errors when I load the page.

@jasonnutter
Copy link
Contributor

@nfgallimore Can you catch the errors that are thrown by the interceptor when you make the http calls?

Regardless, the best way to mitigate this is to use a blank page (which has no content) as your redirect uri. I'll update the Angular samples soon (this week, hopefully) to demonstrate how to do that for Angular.

@nfgallimore
Copy link

@jasonnutter Awesome thanks Jason. Unfortunately the way the interceptor works I cannot think of a way to catch the exception. I could try copying the source code for the MSAL Interceptor and adding it to my project and adding a try/catch. If you wouldn't mind would you please post something in here when you update the sample so I can update my application to not have tons of console exceptions 😄

@jasonnutter
Copy link
Contributor

@nfgallimore You can add error handling at the place where you initiate the http request.

@EricForgy
Copy link

Hi,

I am a noob with this stuff and it was somewhat miraculous I got this to work at all in the first place. Now I am seeing this error suddenly. I've read the above comments but not entirely clear on how they apply to me. Could someone help me understand, in basic terms, what is going on and how I can fix it?

I've got a React app built starting with create-react-app and using mobx-state-tree for state management. My msal instance is accessed through getEnv and I am calling acquireTokenSilent as an action: getAccessToken. Every time I make an API call, I include MSAL.getAccessToken() as one of my arguments. As far as I know, my redirect does not have a hash in it.

I am redirecting back to the same page that created the msal instance though. Is that the problem?

@jasonnutter
Copy link
Contributor

@EricForgy When MSAL needs to make a network request to obtain a new access token (as opposed to using a cached token), it will use a hidden iframe, initially set to load a location on a MSFT backend service. When the backend service has completed generating the token, it will redirect the iframe to your redirect URI (specified in your configuration or on the specific request) with the access token in the hash of the URL. This error occurs when MSAL detects that the page used as the redirect URI (which is now loading inside the hidden iframe with the new access token in the hash of the url) is calling acquireTokenSilent inside the hidden iframe. This error is mostly informative, as it does not block the acquisition of the access token, and it prevents MSAL from trying to acquire another access token inside that hidden iframe (which would open a second, nested hidden iframe).

To mitigate this error, you can either prevent the page used as the redirect URI from calling acquireTokenSilent when loaded inside a hidden iframe (when there is a hash in the url), or you can use completely blank html page for your redirect URI (which is supported for silent and popup requests).

@Marcelh1983
Copy link

Calling acquireTokenSilent on page load in an Angular page using the msalIntercepter is hard to avoid. I think checking if the code is running from an iframe in the acquireTokenSilent function would solve most issues.
It could be solved in library?
Like:

 public acquireTokenSilent(request: AuthenticationParameters): Promise<AuthResponse> {
  const isIframe = window !== window.parent && !window.opener;
  if (!isIframe){ 
   return super.acquireTokenSilent(request).......
  } else {
 Promise.resolve(null);
}

Or in the interceptor. If it's not handled in library you could extend the msalInterceptor:

 intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
  if (!isIframe){ 
  return super.intercept(req,next);
  }
 }

@nubianMONK
Copy link

@jasonnutter Facing same issue as nfgallimore, using the interceptor etc... You mentioned above updating the Angular samples, to demonstrate resolving this in Angular, so just checking to see if you've had a chance to do that? Your help with this is greatly appreciated.

@darianaBarbulMindit
Copy link

@Marcelh1983, I used your solution in my custom interceptor and it worked on one hand, now I don't get the error anymore, but I still have other problem.
After I logged in once, logged out and then tried to login again, looks like the access token is not retrieved and the user is not logged into the application. After Empty Cache and Hard Reload, the user gets logged in.
I tried this on the following browsers: Edge, Firefox and Chrome and the issue only appears in Chrome browser.
Do you have any idea why?

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Aug 27, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
question Customer is asking for a clarification, use case or information.
Projects
None yet
Development

No branches or pull requests

8 participants