Reputation: 102
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.
Upvotes: 2
Views: 2820
Reputation: 102
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
.
Upvotes: 1