2

I built an Angular application following this example: https://github.com/microsoftgraph/msgraph-training-angularspa

I'm able to login and even authenticate to MS Graph from the Angular app.

I'm trying to pass the token to an API service that I have created as well. However I keep getting the below error:

WWW-Authenticate: Bearer error="invalid_token", error_description="The signature is invalid"

I've tried everything possible so far was no luck. I continue to get this error. I've tried the AzureADBearer library:

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

services.Configure<JwtBearerOptions>(AzureADDefaults.JwtBearerAuthenticationScheme, options => 
{
    options.Authority += "/v2.0";
    options.TokenValidationParameters.ValidAudiences = new string[]
    {
        options.Audience, $"api://{options.Audience}"
    };

    options.TokenValidationParameters.ValidateIssuer = false;
    options.TokenValidationParameters.IssuerValidator = AadIssuerValidator.GetIssuerValidator(options.Authority).Validate;
});

I've also tried the Microsoft.Identity.Web library but I'm getting the same error:

services.AddProtectedWebApi(Configuration);

I've been searching for few days now, I've found others with the same problem but so far no clear solution. Any help would be appreciated.

EDIT

I'm trying to build an application for my organization that uses our AzureAD for authentication. The application has Angular frontend with aspnetcore webapi as backend. I'm not too particular on how to get this achieved. Just looking for away to get it done.

12
  • 1
    How does the token you are sending look like? It is possible your API in AAD is configured to get v1 tokens. In that case the signing keys might be different. You can tell if it is a v1 token by looking at the issuer claim (iss); v1 tokens have https://sts.windows.net/guid. You can inspect the token at e.g. jwt.ms. Commented Mar 29, 2020 at 9:52
  • It's a v1 token. Although my endpoint is pointing to v2 and app manifest is set to return v2 tokens, the token that I'm receiving is v1. Commented Mar 29, 2020 at 16:53
  • Okay, that's odd 🤔 How are you acquiring the token? What are you using as the scope? Commented Mar 29, 2020 at 16:55
  • 1
    Okay, the audience in the token your API is receiving should match the API client id or app id URI. Otherwise you may be sending a MS Graph API token to your API, which is not correct. Commented Mar 29, 2020 at 19:06
  • 1
    @juunas thank you your respond on another post has also helped me find the answer Commented Mar 31, 2020 at 13:23

1 Answer 1

1

So after some assistance from Junnas and NanYu and few old posts, I figured out the issue. In my previous setup I had the scopes for my Api and MS Graph together, but the problem is that the token returned for each is different. I needed to acquire different tokens when reaching the different Api (mine vs Graph). After splitting the scopes and acquiring the token independently, I was able to authenticate with both. Also the MsalInterceptor work very well if setup correctly and saves me from writing separate calls to acquire the tokens. Here's my code:

oauth.ts

export const OAuthSettings = {
    appId: '{client Id}',
    authority: 'https://login.microsoftonline.com/{tenant Id}',
    apiScopes: [
        'api://{api id}/access_as_user'
    ],
    graphScopes: [
        'user.read'
    ]
}

app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
import { MsalModule, MsalInterceptor } from '@azure/msal-angular';
import { LogLevel } from 'msal';

import { AppComponent } from './app.component';
import { OAuthSettings } from '../oauth';

// this is only for logging and tracing
export function msalLogCallBack(level: LogLevel, message: string, containsPii: boolean) {
  console.log('[MSAL]:' + message);
}

@NgModule({
  declarations: [
    AppComponent,
  ],
  imports: [
    BrowserModule,
    HttpClientModule,
    MsalModule.forRoot({
      clientID: OAuthSettings.appId,
      authority: OAuthSettings.authority,
      unprotectedResources: ['{angular app uri}'],
      protectedResourceMap: [
        ['{api endpoint}', OAuthSettings.apiScopes],
        ['https://graph.microsoft.com/v1.0/me', OAuthSettings.graphScopes]
      ],
      level: LogLevel.Verbose,
      logger: msalLogCallBack
    })
  ],
  providers: [ {
    provide: HTTP_INTERCEPTORS,
    useClass: MsalInterceptor,
    multi: true
}],
  bootstrap: [AppComponent]
})
export class AppModule { }

From this point any calls made to the Api will be intercepted and the correct token will be attached in the header of the call by the MsalInterceptor.

Sign up to request clarification or add additional context in comments.

1 Comment

Hello @spider913 I followed your solution but I still getting errors. So, did you change something to your Startup.cs of your API? You still use v2 of Authority? Also I'm getting error to AadIssuerValidator. I'm using dotnetcore 3.1

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.