Search code examples
reactjsazureauthenticationazure-ad-msalmsal-react

Azure MSAL React apps using same authentication/user across multiple apps


I have multiple separate React apps using @azure/msal-react for authentication. They are both single-tenant (the same tenant) apps. However, some of our users (mainly admins) have multiple Microsoft user accounts. When they log into one site (SPA 1), that account is automatically used for the other site (SPA 2).

Here is how they are configured:

export const msalConfig = {
  auth: {
    clientId: ***EACH SITE HAS A UNIQUE CLIENT ID***,
    authority: ***EACH SITE HAS THE SAME AUTHORITY URL***,
    redirectUri: ***EACH SITE HAS A UNIQUE REDIRECT URI,
  },
  cache: {
    cacheLocation: 'localStorage', // This configures where your cache will be stored
    storeAuthStateInCookie: true, // Set this to "true" if you are having issues on IE11 or Edge
  }
}

Basically if they have logged in with any account with this tenant in the same browser, it carries over to all other sites, but I don't want that to happen.

  • Login process works well, outside of this case.
  • Expectation is for user to log in with whatever Microsoft account they want for each site and store that specific site's auth state in localStorage across browser sessions.

Solution

  • I created two separate React apps using @azure/msal-react for authentication.

    Even I got the same issue when I tried your code.

    I've used prompt parameter to the login request object in your code. prompt:"select_account"

    export  const  loginRequest  = {
    scopes: ["User.Read"],
    prompt:  "select_account"
    };
    
    • This will ensure the user has to select or enter their credentials each time.

    This is my complete authConfig.js:

    export const msalConfig = {
        auth: {
          clientId: 'your-client-id',
          authority: 'https://login.microsoftonline.com/your-tenant-id',
          redirectUri: 'http://localhost:3000',
        },
        cache: {
          cacheLocation: 'localStorage', 
          storeAuthStateInCookie: false,   
        }
      };
      export const loginRequest = {
        scopes: ["User.Read"],
        prompt: "select_account" 
      };  
    

    This is App.js file:

    import React, { useEffect } from 'react';
    import { useMsal } from '@azure/msal-react';
    import { loginRequest } from './authConfig';
    
    const App = () => {
      const { instance, accounts } = useMsal();
    
      useEffect(() => {
        console.log('Local Storage:', localStorage);
      }, []);
    
      const handleLogin = () => {
        instance.loginPopup(loginRequest).catch(e => {
          console.error(e);
        });
      };
    
      const handleLogout = () => {
        instance.logoutPopup().catch(e => {
          console.error(e);
        }).finally(() => {
          localStorage.clear();  
        });
      };
    
      return (
        <div>
          <h1>Site</h1>
          {accounts.length > 0 ? (
            <div>
              <p>Welcome, {accounts[0].name}</p>
              <button onClick={handleLogout}>Logout</button>
            </div>
          ) : (
            <button onClick={handleLogin}>Login</button>
          )}
        </div>
      );
    };
    
    export default App;
    
    

    Output:

    SITE A:

    enter image description here

    enter image description here

    SITE B:

    Here, Site B is handling authentication independently.

    enter image description here