Amirmasoud
Amirmasoud

Reputation: 21

monitor_window_timeout using msal-browser

I'm getting BrowserAuthError: monitor_window_timeout: Token acquisition in iframe failed due to timeout. I think it is happening as a result of calling ssoSilent but, I have no idea why is it happening. I have read through the documents and the most common case is being redirect away from redirectUri. I don't think that is my issue though since I am using a completely blank html page as my redirect destination when calling a silent api on MSAL.

      const result = await this.instance.ssoSilent({
        loginHint: userEmail,
        scopes: this.authConfig.scopes,
        redirectUri: this.authConfig.silentRedirectUri,
      })
      this.instance.setActiveAccount(result.account)
    } catch (error) {
      if (error instanceof InteractionRequiredAuthError) {
        await this.loginRedirect(userEmail)
        return
      }
      throw error
    }

I expect that the hidden iframe not to timeout and handles the redirect response correctly

Upvotes: 0

Views: 59

Answers (1)

Dasari Kamali
Dasari Kamali

Reputation: 3649

Many mobile browsers like Chrome in Android's incognito mode block third-party cookies by default. Since MSAL relies on cookies for session continuity, iframe authentication may fail due to these restrictions.

I tried the below Vue 3 app configuration for Silent Authentication to obtain the Access Token.

msalConfig.js :

import { PublicClientApplication } from "@azure/msal-browser";

const msalConfig = {
  auth: {
    clientId: "<clientID>",
    authority: "https://login.microsoftonline.com/<tenantID>",
    redirectUri: "http://localhost:5173/", 
    postLogoutRedirectUri: "http://localhost:5173/",
  },
  cache: {
    cacheLocation: "localStorage",
    storeAuthStateInCookie: true, 
  }
};

const msalInstance = new PublicClientApplication(msalConfig);
const initializeMsal = async () => {
  await msalInstance.initialize();
};
export { msalInstance, initializeMsal };

authService.js :

import { msalInstance, initializeMsal } from "./msalConfig";
import { InteractionRequiredAuthError } from "@azure/msal-browser";

export async function login(userEmail) {
  try {
    await initializeMsal();
    const result = await msalInstance.ssoSilent({
      loginHint: userEmail,
      scopes: ["User.Read"],
      redirectUri: "http://localhost:5173/silent-auth",
    });

    msalInstance.setActiveAccount(result.account);
    return result;
  } catch (error) {
    if (error instanceof InteractionRequiredAuthError) {
      return msalInstance.loginRedirect({
        scopes: ["User.Read"],
        loginHint: userEmail
      });
    }
    console.error("Login error:", error);
  }
}

export async function logout() {
  try {
    await msalInstance.logoutRedirect();
  } catch (error) {
    console.error("Logout error:", error);
  }
}
export async function getToken() {
  try {
    const account = msalInstance.getActiveAccount();
    if (!account) throw new Error("No active account found");

    const response = await msalInstance.acquireTokenSilent({
      account,
      scopes: ["User.Read"]
    });
    return response.accessToken;
  } catch (error) {
    console.error("Token acquisition failed:", error);
    throw error;
  }
}

I have added the below URL's in the service principle > Authentication > Single-page application and Enabled the Allow public client flows.

http://localhost:5173/silent-auth
http://localhost:5173/

enter image description here

Output :

I successfully authenticated and got the Access Token.

enter image description here

enter image description here

enter image description here

Upvotes: 0

Related Questions