Angular MSAL AD 401 Unauthorized in Angular App but 200 Ok in Postman - ASP.NET Core Web API

Viewed 2583

Good day,

I'm trying to fetch data from my ASP.NET Core Web API using Angular MSAL, but I'm having an error in my angular app that says 401 Unauthorized Error.

I tried to get the access_token in the application tab of the browser and use it on Postman, and technically it works. I just got no idea why it throws the Unauthorized 401 error in my angular app.

Here's my app.module.js

export const protectedResourceMap: [string, string[]][] = [
  ['https://graph.microsoft.com/v1.0/me', ['user.read']]
];

const isIE = window.navigator.userAgent.indexOf("MSIE ") > -1 || window.navigator.userAgent.indexOf("Trident/") > -1;

imports: [
// msal angular
     MsalModule.forRoot({
        auth: {
            clientId: 'MYCLIENTID-FROMAD',
            authority: "https://login.microsoftonline.com/common/",
            validateAuthority: true,
            redirectUri: "http://localhost:4200/",
            postLogoutRedirectUri: "http://localhost:4200/",
            navigateToLoginRequestUrl: true,
        },
        cache: {
            cacheLocation : "localStorage",
            storeAuthStateInCookie: true, // set to true for IE 11
        },
        framework: {
            unprotectedResources: ["https://www.microsoft.com/en-us/"],
            protectedResourceMap: new Map(protectedResourceMap)
        },
      }, {
        popUp: !isIE,
        extraQueryParameters: {}
    })
],
providers: [
    {
        provide: HTTP_INTERCEPTORS,
        useClass: MsalInterceptor,
        multi: true
      }
   ],

Here's my ASP.NET Core Web API host: http://localhost:5000

Where it implements [Authorize] in some of its Controllers. I think there's a problem in my backend since everything is working using my access_token from my local storage when I tested it using Postman with authorization header of Bearer access_token.

Browser Application Tab after successfully login

Thank you in advance.

1 Answers

The main thing you are missing in my opinion is the protected resource map configuration. Currently it only defines MS Graph API. You should add your own API there as well:

export const protectedResourceMap: [string, string[]][] = [
  ['https://graph.microsoft.com/v1.0/me', ['user.read']],
  ['http://localhost:5000', ['your-api-client-id/user_impersonation']]
];

Replace your-api-client-id with the client id/application id for your API. You can also use the application ID URI for the API. The last part is the scope, change user_impersonation to a scope you have defined on the API (can be done through Expose an API in Azure Portal).

Now when it sees an HTTP request to http://localhost:5000, it'll know to get a token for it and attach it to the request.

Related