jqueryauthenticationazure-active-directoryasp.net-core-webapiazure-ad-msal

Azure AD Authentication 401 error "the audience is invalid" AddAzureADBearer .Net Core Web Api


I'm trying to create a simple example of Azure AD authentication using this sample except for my client is JQuery. I am not sure why I get the 401 error about the audience is invalid when the token shows the audience is https://myportal.onmicrosoft.com/test_core_web_api_spa. This matches the API definition in Azure. The only missing piece is the custom scope of user_impersonation but when I make the call using MSAL clientApplication.acquireTokenSilent(tokenRequest2) to acquire the token it my scopes matches the full URL of the API with scope:

const tokenRequest2 = {
    scopes: ["https://myportal.onmicrosoft.com/test_core_web_api_spa/user_impersonation"]
};

In the API to establish authentication I am using this code (I noticed not many examples use this method)

services.AddAuthentication(AzureADDefaults.BearerAuthenticationScheme)
   .AddAzureADBearer(options => Configuration.Bind("AzureAd", options));

And the configuration for the API is

  "AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "Domain": "myportal.onmicrosoft.com",
    "TenantId": "my-tenant-guid",
    "ClientId": "my-api-client-guid"
  },

I've noticed many examples showing a different format for the API (I assume these are older version) but the exposed API scope is listed in Azure as https://myportal.onmicrosoft.com/test_core_web_api_spa/user_impersonation. I have also added the guid of the client using the Azure dashboard to access this exposed API scope.

Any ideas where I have gone wrong? Alternately, any simple examples using MSAL, JQuery for the client, and a simple .Net Core Web Api? Seems like all the examples I find are out of date or use a different client or a different authentication method.

Update to show expose api settings in Azure for web api app. I've added an image from Azure showing the settings for the "expose an api" screen. I've added the custom scope user_impersonation then added the client and granted it access to that scope. As you can see my Azure subscription does not have the api://guid format that is seen by others. When I try to use that api://guid format I get the error The resource principal named api://guid was not found in the tenant.

I also added image of the token. The aud tag matches my web api app name in Azure. And the scp lists the scope that I attached to my scopes request. I just cannot see what else to try.

enter image description here

expose api settings for web api


Solution

  • The problem was the configuration data for the Web API. When they say the ClientId what they really want is the value under the "expose an API" option where it says "Application ID URI". What I was putting in there was the guid for the Web Api application registration. Below is how it should look.

      "AzureAd": {
        "Instance": "https://login.microsoftonline.com/",
        "Domain": "myportal.onmicrosoft.com",
        "TenantId": "mytenant-guid",
        "ClientId": "https://myportal.onmicrosoft.com/test_core_web_api_spa"
      },
    

    Note on the API format. It appears that when you register the application directly in Azure the format for the exposed API will be api://app-guid. But if you first create your application using Visual Studio then the format will default to something like https:///myportal.onmicrosoft.com/project-name-in-visual-studio.