Home > Software design >  Azure AD Authentication with .NET Core Web API
Azure AD Authentication with .NET Core Web API

Time:02-04

We have a simple setup. Frontend web application gets a token from Azure AD. Frontend uses that token to authenticate requests to our backend .NET Core Web API. Both will be deployed as Azure Web Apps.

We have found a number of resources on this subject (enter image description here

  • Then navigate to the Frontend app registration -> API Permissions -> Add a permission -> Add Access to API exposed in step 2. enter image description here

  • Then select "Grant Admin Consent"

  • Onto the Frontend code:

  • On the Frontend we are using Microsoft's MSAL library. We have it configured as such:

  • // Frontend msal config
       {
            msalConfig: {
            auth: {
                clientId: "{frontend clientId}",
                authority: "https://login.microsoftonline.com/{tenantId}/",
                redirectUri: appUri,
                postLogoutRedirectUri: appUri,
                mainWindowRedirectUri: appUri
            },
            cache: {
                cacheLocation: 'localStorage'
            }
        }
    
    1. We send a login request:
    // login.js
            const request = {
                scopes: [
                    "User.Read", 
                    "api://{Backend Application Id From AzureAD App Registration}/access_as_user"
                ]
            };
            instance.loginPopup(request).catch(
                (error) => {
                    console.log(error);
                }
            );
    
    
    1. This works as expected and users are able to login and out of our frontend application.
    2. We place our Azure AD provided token in our Authorization header in requests to our backend API (always returns a 401).
    3. Backend code using Microsoft.Identity.Web (.NET 5):
    // .Net appsettings.json  
     "AzureAd": {
       "Instance": "https://login.microsoftonline.com/",
       "ClientId": "{backend clientId}",
       "TenantId": "{tenantId}"
     }
    
    // Startup.cs
    
    using Microsoft.Identity.Web;
    
    ConfigureServices(IServiceCollection services)
    {
     //other services
     services.AddMicrosoftIdentityWebApiAuthentication(Configuration, "AzureAd");
     //other services
    }
    
    Configure(IApplicationBuilder app, IWebHostEnvironment env)
    { 
     // other config
     app.UseRouting();
     app.UseAuthentication();
     app.UseAuthorization();
     // other config
    }
    

    Any help on how to proceed would be greatly appreciated. We are testing locally right now, but once we get auth working we will be deploying the frontend & backend applications to Azure Web Apps.

    UPDATE:

    I can see in the 401 response headers that I am getting:

    Bearer error="invalid_token", error_description="The signature is invalid"

    CodePudding user response:

    1. Try to add "Audience" parameter into AzureAD section: "Audience": "api://{Client_Id}".

    2. To receive more info about auth you can pass subscribeToJwtBearerMiddlewareDiagnosticsEvents: true into services.AddMicrosoftIdentityWebApiAuthentication and check your logs after unsuccessful request.

    3. Also, you can decode(https://jwt.io) your token and check the payload section if there are required scope and audience.

    4. It could be that token (provided to backend) is actually for Microsoft Graph(check appId here: shawntabrizi.com/aad/…). If "scp" is "openid profile User.Read email" and "aud" is "00000003-0000-0000-c000-000000000000" then you are using the wrong token for your backend. Ask Frontend to check the way how they are receiving a token.

    Frontend guy put something like this into code, correct me if I am wrong:

     
     public static msalInterceptorConfigFactory(): MsalInterceptorConfiguration {
        const resourceMap = new Map<string, Array<string>>();
        resourceMap.set(environment.apiUrl, [environment.scope]);
    
        return {
          interactionType: InteractionType.Redirect,
          resourceMap
        };
      }
    
      public static msalGuardConfigFactory(): MsalGuardConfiguration {
        return {
          interactionType: InteractionType.Redirect,
          authRequest: {
            scopes: [environment.scope]
          }
        };
      }
    
    # module.ts
     providers: [
    ...
        {
          provide: MSAL_GUARD_CONFIG,
          useFactory: msalGuardConfigFactory
        },
        {
          provide: MSAL_INTERCEPTOR_CONFIG,
          useFactory: msalInterceptorConfigFactory
        },
    ...
      ],

    •  Tags:  
    • Related