I am using an react app to call azure apis. This is how it is setup:
import { BrowserAuthError, PublicClientApplication } from '@azure/msal-browser';
import { MsalProvider, useMsal, AuthenticatedTemplate, UnauthenticatedTemplate } from '@azure/msal-react';
import { msalConfig } from './authConfig';
const pca = new PublicClientApplication(msalConfig);
const { instance, accounts } = useMsal();
const loginRequest = {
scopes: ["User.Read"],
};
const response = await instance.acquireTokenPopup(loginRequest);
const accessToken = response.accessToken;
const fetchResponse = await fetch('https://management.azure.com/subscriptions/<subid>/resourceGroups/<rg>/providers/Microsoft.Network/frontDoors/<afd>?api-version=2021-06-01', {
headers: {
Authorization: `Bearer ${accessToken}`,
},
});
const data = await fetchResponse.json();
This is what I have in authConfig
const msalConfig = {
auth: {
clientId: <clientId>,
authority: `https://login.microsoftonline.com/<tenantId>`,
redirectUri: window.location.origin,
},
cache: {
cacheLocation: "sessionStorage",
storeAuthStateInCookie: false,
},
};
I have configured the following permissions in the app and I also created a service principal and gave it contributor access to the subscription. I am able to get the token using this code but using that token is resulting in
{
"error": {
"code": "AuthenticationFailed",
"message": "Authentication failed."
}
}
Am I missing any step here?
On adding the azure service management API permissions, I am being asked for admin approval.
This is the enterprise applications settings:
Initially I created a Microsoft Entra ID application and added API permissions like below:
I added contributor role to Service Principal as you:
When I tried to access the API, I got the similar error as you:
The error usually occurs if the required API permissions are not granted to the Microsoft Entra ID application.
To resolve the error, you need to add Azure Service Management delegated API permission like below:
And in the code pass scope as https://management.azure.com/user_impersonation
like
scopes: ["https://management.azure.com/user_impersonation"]
I am able to fetch the API results successfully as below:
const pca = new PublicClientApplication(msalConfig);
function FetchDataComponent() {
const { instance, accounts } = useMsal();
const [data, setData] = useState(null);
const [error, setError] = useState(null);
const loginRequest = {
scopes: ["https://management.azure.com/user_impersonation"],
};
const fetchData = async () => {
try {
const response = await instance.acquireTokenPopup(loginRequest);
const accessToken = response.accessToken;
const fetchResponse = await fetch('https://management.azure.com/subscriptions/xxx/resourceGroups/ruk/providers/Microsoft.Network/frontDoors?api-version=2019-05-01', {
headers: {
Authorization: `Bearer ${accessToken}`,
},
});
if (!fetchResponse.ok) {
throw new Error(`HTTP error! status: ${fetchResponse.status}`);
}
const data = await fetchResponse.json();
setData(data);
} catch (err) {
setError(err.message);
}
};
return (
<div>
<button onClick={fetchData}>Fetch Data</button>
{error && <p>Error: {error}</p>}
{data && <pre>{JSON.stringify(data, null, 2)}</pre>}
</div>
);
}
function App() {
return (
<MsalProvider instance={pca}>
<AuthenticatedTemplate>
<FetchDataComponent />
</AuthenticatedTemplate>
<UnauthenticatedTemplate>
<p>Please sign in to see the data.</p>
</UnauthenticatedTemplate>
</MsalProvider>
);
}
export default App;
As I do not have any front door I got empty output: