Description
Core Library
MSAL.js (@azure/msal-browser)
Core Library Version
3.6.0
Wrapper Library
Not Applicable
Wrapper Library Version
None
Public or Confidential Client?
Public
Description
I am working on adopting MSAL.js in vscode.dev… this has been quite the challenge. The current challenge I’ve been working on is:
We set the following headers:
'Cross-Origin-Opener-Policy', 'same-origin'
to have access to browser APIs that require cross origin isolation (shared array buffers)
The popup flow doesn't seem to work in this context. I get the popup, and go through the auth flow, but then I'm stuck on my redirectUri's page:
In my proof of concept I worked around this issue by doing:
'Cross-Origin-Opener-Policy', 'same-origin-allow-popups'
but that does not count for cross origin isolation and so other features that require this break down.
We have to use same-origin
. There’s no way around that… so I need a solution using MSAL.
We can’t take the user through the redirect flow in the vscode.dev tab because they have context we don’t want to be lost…
Note, there is a new property for COOP in the pipeline that should make this all potentially "just work" https://developer.chrome.com/blog/coop-restrict-properties but we are a long way away from general availability.
Additionally, that still would not fix the issue for clients who still want to use same-origin
.
Perhaps there is a way to play nice with same-origin
but I do feel like you can't do much without control of the code that runs in the redirectUri... but maybe I'm wrong.
In my testing, the only way around this issue is to:
- launch my own popup that we own (like vscode.dev/microsoftAuthPopup) and then
- a page is served in this popup that will use the MSAL redirect flow (so a redirect flow inside of a popup owned by the client, not MSAL) - we use local storage as the storage for MSAL btw
- When MSAL finishes we use a BroadcastChannel to inform the main window that the flow succeeded and
- then main window attempt to acquire a token silently... which works since the flow stored the token in local storage.
- Then, the popup closes itself.
This is a lot for me to do myself.
Idea:
Since it is theoretically possible to do this, I wonder if MSAL.js should have a handlePopupPromise()
function that could be run inside of a redirectUri
popup that is essentially a manual version to inform the parent window that the flow has succeeded. This function could send a message back to the main window, and close the popup.
Error Message
The error that is logged on the parent window is that the user canceled the flow. This is because the popup is running in a different browser context because it is in a different origin.
MSAL Logs
No response
Network Trace (Preferrably Fiddler)
- Sent
- Pending
MSAL Configuration
{
auth: {
clientId,
authority: `${MicrosoftAuthenticationProvider._DEFAULT_AAD_ENDPOINT}${tenant}`,
redirectUri: MicrosoftAuthenticationProvider._REDIRECT_ROUTE,
},
cache: {
cacheLocation: 'localStorage'
},
system: {
loggerOptions: {
loggerCallback: (level: LogLevel, message: string, containsPii: boolean): void => {
if (containsPii) {
return;
}
switch (level) {
case LogLevel.Error:
console.error(message);
return;
case LogLevel.Info:
console.info(message);
return;
case LogLevel.Verbose:
console.debug(message);
return;
case LogLevel.Warning:
console.warn(message);
return;
}
},
piiLoggingEnabled: false,
},
},
}
Relevant Code Snippets
await msalObj.loginPopup({ scopes: resolvedScopes, prompt: 'select_account', loginHint: accountId });
Reproduction Steps
Serve a SPA with the headers:
'Cross-Origin-Opener-Policy', 'same-origin'
'Cross-Origin-Embedder-Policy', 'require-corp'
in that SPA, do the regular old popup flow.
Expected Behavior
Popup flow works
Identity Provider
Entra ID (formerly Azure AD) / MSA
Browsers Affected (Select all that apply)
Chrome, Edge, Safari
Regression
No response
Source
Internal (Microsoft)