Microsoft SSO login is not working as intended in react app

344 views Asked by At

I am trying to do a microsoft SSO login in my react application using dynamic credentials for SSO login of client id, tenant id. The problem is that it is not working. It will just open a popup page and when I click on the user account it will just simple redirect to redirect url in the same page instead of closing up and returning me the result.

This happens when I am getting same credentials from database but when i am using them hardcoded it is working perfectly as it needs to be.

I have checked the data which I get from database and it is working fine there so trying to resolve it but I have no idea why it is behaving in this way.

here is my code below

function LoginButton() {
  const { instance } = useMsal();

  const handleLogin = async() => {
    instance.loginPopup().then((response) => {
      console.log(response);
    }).catch((error) => {
      console.log(error);
    });
  }

  return <button type="button" onClick={handleLogin} className="btn btn-primary">Login</button>;
}

function App() {
  const [msalConfig, setMsalConfig] = useState<Configuration | null>(null);
  const [isLoading, setIsLoading] = useState(true);
  
  useEffect(() => {
    const MFTLogin = async () => {
      const subdomain = window.location.hostname.split('.')[0];
      const storedConfig = localStorage.getItem('msalConfig');

      if (storedConfig) {
        setMsalConfig(JSON.parse(storedConfig));
        setIsLoading(false);
      } else if (subdomain) {
        // Fetch and set MSAL configuration
        const request = await axios.get(`http://localhost:5000/outlook/organization/${subdomain}`);
        if (request && request.data) {
          const data: Configuration = {
            auth: {
              clientId: request.data.data.outlook_client_id_mfo,
              authority: `https://login.microsoftonline.com/${request.data.data.outlook_tenant_id_mfo}`,
              redirectUri: "http://localhost:3000",
            }
          };
          localStorage.setItem('msalConfig', JSON.stringify(data));
          setMsalConfig(data);
        }
        setIsLoading(false);
      }
    };

    MFTLogin();
  }, []);

  if (isLoading) {
    return <div>Loading...</div>;
  }

  if (!msalConfig) {
    return <div>Configuration Error</div>;
  }

  const msalInstance = new PublicClientApplication(msalConfig);

  return (
    <MsalProvider instance={msalInstance}>
      <div className="App">
        <LoginButton />
      </div>
    </MsalProvider>
  );
}

export default App;
1

There are 1 answers

1
Dasari Kamali On BEST ANSWER

I tried the below code and was able to log in to my react application using dynamic credentials for SSO login of client ID, tenant ID.

Code :

src/components/LoginButton.js :

import React from 'react';
import { useMsal } from '@azure/msal-react';
import { setMsalConfig } from '../services/authService'; 
import { fetchMsalConfigFromApi } from '../services/apiService'; 

const LoginButton = () => {
  const { instance } = useMsal();

  const handleLogin = async () => {
    let apiConfig; 

    try {
      const subdomain = window.location.hostname.split('.')[0];
      apiConfig = await fetchMsalConfigFromApi(subdomain);

      setMsalConfig({
        auth: {
          clientId: apiConfig.outlook_client_id_mfo,
          authority: `https://login.microsoftonline.com/${apiConfig.outlook_tenant_id_mfo}`,
          redirectUri: 'http://localhost:3000',
        },
      });

      await instance.loginPopup();
    } catch (error) {
      console.log('Error during login:', error);
    }
  };

  return (
    <button type="button" onClick={handleLogin} className="btn btn-primary">
      Login
    </button>
  );
};

export default LoginButton;

src/services/apiService.js :

import axios from 'axios';
const fetchMsalConfigFromApi = async (subdomain) => {
  try {
    const response = await axios.get(`http://localhost:5000/outlook/organization/`);
    return response.data.data;
  } catch (error) {
    console.error('Error fetching MSAL config from API:', error);
    throw error;
  }
};

export { fetchMsalConfigFromApi };

server/server.js :

const express = require('express');
const cors = require('cors');
const app = express();
const port = 5000;

const msalConfig = {
  outlook_client_id_mfo: '<client_ID>',
  outlook_tenant_id_mfo: '<tenant_ID>',
};

app.use(cors());

app.get('/outlook/organization', (req, res) => {
  res.json({
    success: true,
    data: msalConfig,
  });
});

app.listen(port, () => {
  console.log(`Server is running on port ${port}`);
});

I added the below URL as a Single-page application in the app authentication as below,

 http://localhost:3000

enter image description here

Output :

The server side code is running on the port 5000 as below,

enter image description here

I got the below output with the above output URL in the browser,

enter image description here

The client-side code is running on port 3000 as below,

enter image description here

I clicked on the Login button and selected my account for login. I was able to log in.

enter image description here