AzureAD / microsoft-authentication-library-for-js

Microsoft Authentication Library (MSAL) for JS
http://aka.ms/aadv2
MIT License
3.64k stars 2.65k forks source link

How to verify authentication state in new tab with session storage #2986

Closed mleimer closed 3 years ago

mleimer commented 3 years ago

Library

Description

Given that we use SessionStorage and do NOT want to use LocalStorage to share the login state across multiple tabs, is there another official way how to silently verify if a user is authenticated or not when the user just opened a new tab?

Since instance.getAllAccounts() will for obvious reasons return nothing when a new tab is opened, I cannot use 'instance.acquireTokenSilent(), as this method call requires an account. I could doinstance.loginRedirect()`, yet that is not a silent call as the user would be presented the login mask if he is indeed not authenticated.

I identified a non-documented solution by calling instance.ssoSilent(). According to documentation, calling ssoSilent must be done with either a loginHint or an sid. Since I just loaded the application in a new tab, I do not have either value. Yet, if I pass a single space character ' ' as the sid or the loginHint, it appears to work as well. I would like to understand why that is working, if that is a bug or whether this is actually ok to do so.

We are using Azure AD B2C with Authorization Code Flow with PKCE.

const { instance } = useMsal();

const checkAuthenticationState = () => {
  instance
    .ssoSilent({
      scopes: ['openid'],
      sid: ' ',
      redirectUri: '<someRedirectUri>',
    })
    .then(() => {
      // user is authenticated
    })
    .catch(() => {
      // user is not authenticated
    });
};

useEffect(() => {
 ...
 checkAuthenticationState();
 ...
}, [...]);

Source

hectormmg commented 3 years ago

Hi @mleimer

I identified a non-documented solution by calling instance.ssoSilent(). According to documentation, calling ssoSilent must be done with either a loginHint or an sid. Since I just loaded the application in a new tab, I do not have either value. Yet, if I pass a single space character ' ' as the sid or the loginHint, it appears to work as well. I would like to understand why that is working, if that is a bug or whether this is actually ok to do so.

I would advise against this workaround since it's not the expected functionality and is unlikely to work in the future (I believe it is a bug).

Given that we use SessionStorage and do NOT want to use LocalStorage to share the login state across multiple tabs

Do you mean you don't want to use localStorage at all or just for the MSAL cache? If there's some flexibility there, a valid solution would be for you to manually store the loginHint in localStorage, read it from the new tab and send that to ssoSilent. Using localStorage is what allows MSAL to do silent token acquisition across browser tabs, so if that's not an option, your application would have to fallback to an interactive flow and the user would be prompted again.

github-actions[bot] commented 3 years ago

This issue has not seen activity in 14 days. It will be closed in 7 days if it remains stale.

github-actions[bot] commented 3 years ago

This issue has been closed due to inactivity. If this has not been resolved please open a new issue. Thanks!