I am trying to call WebAPI from angularUI using AzureAD protection but I am this facing this error:
zone-evergreen.js:2952 GET https://localhost:44319/api/employee 401:
I have also refered below blog:
Azure AD Authentication In Angular And ASP.NET Core Web API App
msal.service.ts
import { Injectable } from '@angular/core';
import { BroadcastService, MsalService } from '@azure/msal-angular';
import * as Msal from 'msal';
import { environment } from '../../environments/environment';
import { Observable } from 'rxjs';
@Injectable()
export class MsalUserService {
private accessToken: any;
public clientApplication: Msal.UserAgentApplication = null;
constructor() {
this.clientApplication = new Msal.UserAgentApplication(
environment.uiClienId,
'https://login.microsoftonline.com/' + environment.tenantId,
this.authCallback,
{
storeAuthStateInCookie: true,
//cacheLocation: 'localStorage' ,
});
}
public GetAccessToken(): Observable<any> {
if (sessionStorage.getItem('msal.idtoken') !== undefined && sessionStorage.getItem('msal.idtoken') != null) {
this.accessToken = sessionStorage.getItem('msal.idtoken');
console.log(this.accessToken);
}
return this.accessToken;
}
public authCallback(errorDesc, token, error, tokenType) {
if (token) {
} else {
console.log(error + ':' + errorDesc);
}
}
public getCurrentUserInfo() {
const user = this.clientApplication.getUser();
alert(user.name);
}
public logout() {
this.clientApplication.logout();
I have set the environment file as follows:
export const environment = {
production: false,
baseUrl: 'https://localhost:44319/',
scopeUri: ['api://3b4451a3-f813-4980-a477-fa8077138b8a/UserRead'],
tenantId: 'e2xt89c0-058e-4dde-bb96-46de5ff97fe5',
uiClienId: '9ebpqb4f-ee19-43c4-a221-2fec4930a1ec',
redirectUrl: 'http://localhost:4200'
};
app.module.ts
import { AppComponent } from './app.component';
import { NavMenuComponent } from './nav-menu/nav-menu.component';
import { HomeComponent } from './home/home.component';
import { CounterComponent } from './counter/counter.component';
import { FetchDataComponent } from './fetch-data/fetch-data.component';
import { EmployeeComponent } from './employee/employee.component';
export const protectedResourceMap: any =
[
[environment.baseUrl, environment.scopeUri
]
];
@NgModule({
declarations: [
AppComponent,
NavMenuComponent,
HomeComponent,
CounterComponent,
FetchDataComponent,
EmployeeComponent
],
imports: [
MsalModule.forRoot({
clientID: environment.uiClienId,
authority: 'https://login.microsoftonline.com/' + environment.tenantId,
protectedResourceMap: protectedResourceMap,
redirectUri: environment.redirectUrl
}),
BrowserModule.withServerTransition({ appId: 'ng-cli-universal' }),
AppRoutingModule,
HttpClientModule,
FormsModule,
],
providers: [HttpClient,
MsalUserService,
{
provide: HTTP_INTERCEPTORS, useClass: MsalInterceptor, multi: true
}
],
bootstrap: [AppComponent]
})
export class AppModule { }
Employee.ts
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Observable } from 'rxjs';
import { environment } from '../../environments/environment';
import { MsalUserService } from '../service/msaluser.service';
import { EmployeeModel } from './employeemodel';
@Injectable({
providedIn: 'root'
})
export class EmployeeService {
private url = environment.baseUrl + 'api/employee';
httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/json'
})
};
constructor(private http: HttpClient, private msalService: MsalUserService
) { }
getEmployees(): Observable<EmployeeModel[]> {
this.httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + this.msalService.GetAccessToken()
})
};
console.log(this.url);
return this.http.get(this.url, this.httpOptions)
.pipe((response: any) => {
return response;
});
}
getCurrentUserInfo() {
this.msalService.getCurrentUserInfo();
}
logout() {
this.msalService.logout();
}
}
appsetting.json
"AzureActiveDirectory": {
"Instance": "https://login.microsoftonline.com/",
"Domain": "mydomain.onmicrosoft.com",
"TenantId": "e2xt89c0-058e-4dde-bb96-46de5ff97fe5",
"ClientId": "api://3bdd4161a3-f813-4980-a477-fa8077138b8a"
}
StartUp.cs
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
// In production, the Angular files will be served from this directory
services.AddSpaStaticFiles(configuration =>
{
configuration.RootPath = "ClientApp/dist";
});
services.AddAuthentication(AzureADDefaults.BearerAuthenticationScheme).AddAzureADBearer(options => Configuration.Bind("AzureActiveDirectory", options));
string corsDomains = "http://localhost:4200";
string[] domains = corsDomains.Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
services.AddCors(o => o.AddPolicy("AppCORSPolicy", builder =>
{
builder.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials()
.WithOrigins(domains);
}));
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseCors("AppCORSPolicy");
app.UseHttpsRedirection();
app.UseStaticFiles();
if (!env.IsDevelopment())
{
app.UseSpaStaticFiles();
}
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller}/{action=Index}/{id?}");
});
app.UseSpa(spa =>
{
// To learn more about options for serving an Angular SPA from ASP.NET Core,
// see https://go.microsoft.com/fwlink/?linkid=864501
spa.Options.SourcePath = "ClientApp";
if (env.IsDevelopment())
{
spa.UseAngularCliServer(npmScript: "start");
}
});
}
EmployeeController.cs
[Authorize]
[Route("api/[controller]")]
[ApiController]
public class EmployeeController : ControllerBase
{
[HttpGet]
public IEnumerable<Employee> Get()
{
List<Employee> employees = new List<Employee>
{
new Employee { Id = 1, Name = "AA", Company = "ABC", City = "xyz" },
new Employee { Id = 2, Name = "BB", Company = "ABC", City = "xyz" },
new Employee { Id = 3, Name = "CC", Company = "ABC", City = "xyz" }
};
return employees;
}
}
It is showing error in network that "zone-evergreen.js:2952 GET https://localhost:44319/api/employee 401"
Please help me to solve this issue. Thank you in advance.