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;
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
Output :
The server side code is running on the port 5000 as below,
I got the below output with the above output URL in the browser,
The client-side code is running on port 3000 as below,
I clicked on the Login button and selected my account for login. I was able to log in.