# Angular + .net Core 5 API + Auth0 : Http 401

**URL:** <https://community.auth0.com/t/angular-net-core-5-api-auth0-http-401/60992>\
**Category:** Get Help\
**Tags:** csharp, angular\
**Created:** [April 12, 2021, 9:20pm UTC](https://community.auth0.com/t/angular-net-core-5-api-auth0-http-401/60992 "2021-04-12T21:20:44Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![hugodufort](https://sea1.discourse-cdn.com/auth0/user_avatar/community.auth0.com/hugodufort/32/14067_2.png) [@hugodufort](https://community.auth0.com/u/hugodufort)\
**Post date:** [April 12, 2021, 9:20pm UTC](https://community.auth0.com/t/angular-net-core-5-api-auth0-http-401/60992/1 "2021-04-12T21:20:45Z")

</div>

Hello there,  
I’m trying very hard to implement Auth0 in my Angular 9.1.14 application, but I can’t still figure out what the problem.

I’ve been able to add login the my my app, but I fail to implement call to my C# .Net Core 5 REST API.  
I’ve flowed the tutorial many time, but still all call I made to my API end with \* HTTP Error. 401\*

**Here more details:**

Angular App config:  
**AppModule:**

```
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { RouterModule } from '@angular/router';
import { AppComponent } from './app.component';
import { NavMenuComponent } from './nav-menu/nav-menu.component';
import { HomeComponent } from './home/home.component';
import { DevicesComponent } from './Device/devices.component';
import { DeviceComponent } from './Device/device.component';
import { SelectListComponent } from './components/selectlist.component/select.list.component'; import { GeneralNoteComponent } from './components/generalNote.compoment/generalNote.compoment'; import { DeviceMaintenanceComponent } from "./components/devicemaintenance.component/devicemaintenance.component"; import { DeviceLoanComponent } from './components/deviceloan.component/deviceloan.component';
import { AuthModule } from '@auth0/auth0-angular'; import { LoggedUserComponent } from './components/loggedUser.Component/loggedUser.Component';
import { LoginComponent } from './components/login.component/login.component';
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
import { AuthHttpInterceptor, AuthGuard } from '@auth0/auth0-angular';
@NgModule({

  declarations: [
    AppComponent,
    NavMenuComponent,
    HomeComponent,
    DevicesComponent,
    DeviceComponent,
    SelectListComponent,
    DeviceMaintenanceComponent,
    DeviceLoanComponent,
    GeneralNoteComponent,
    LoggedUserComponent,
    LoginComponent
  ],
  imports: [
    BrowserModule.withServerTransition({ appId: 'ng-cli-universal' }),
    HttpClientModule,
    FormsModule,
    RouterModule.forRoot([
      { path: '', component: DevicesComponent, canActivate: [AuthGuard] },
      { path: 'login', component: LoginComponent },
      { path: 'device', component: DeviceComponent, canActivate: [AuthGuard] },
      { path: 'generalNote', component: GeneralNoteComponent, canActivate: [AuthGuard] }
    ]),
    AuthModule.forRoot({
      domain: 'dev-***.us.auth0.com',
      clientId: 'Sk ********* dm',
      audience: 'https://dev-***.us.auth0.com/api/v2/',
      httpInterceptor: {
        allowedList: [
          {
            // Match any request that starts 'https://dev-sss.us.auth0.com/api/v2/' (note the asterisk)
            uri: 'https://dev-***.us.auth0.com/api/v2/*',
            tokenOptions: {
              // The attached token should target this audience
              audience: "https://dev-***.us.auth0.com/api/v2/",
              // The attached token should have these scopes
              scope: 'device:read'
            }
          }
        ]
      }
    })
  ],
  providers: [AuthGuard,
    { provide: HTTP_INTERCEPTORS, useClass: AuthHttpInterceptor, multi: true }
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

```

**API Call:**

```
 const options = { params: new HttpParams() };    
 this.http.get<device[]>(this.apiUrl + "device/getall", options)
          .subscribe(
            result => this.devices = result,
            error => console.error(error)
          );

```

**.Net Core 5 API**

```
namespace Equipment.Api
{
    using System;
    using System.Threading.Tasks;
    using Common.Interfaces;
    using Laumie.Infrastructure.Web.Authorization;
    using Laumie.Infrastructure.Web.Middleware;
    using Microsoft.AspNetCore.Authentication.JwtBearer;
    using Microsoft.AspNetCore.Authorization;
    using Microsoft.AspNetCore.Builder;
    using Microsoft.AspNetCore.Hosting;
    using Microsoft.AspNetCore.Http;
    using Microsoft.Extensions.Configuration;
    using Microsoft.Extensions.DependencyInjection;
    using Microsoft.Extensions.Hosting;
    using Microsoft.Extensions.Logging;
    using Microsoft.OpenApi.Models;
    using Presentation;
    using Presentation.Interface;
    using Services;

    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        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.AddControllers();
            services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new OpenApiInfo { Title = "Equipment.Api", Version = "v1" });
            });
            services.AddMvc(x => x.EnableEndpointRouting = false);

            services.AddCors(options =>
            {
                options.AddPolicy("AllowSpecificOrigin",
                    builder =>
                    {
                        builder
                            .WithOrigins("http://localhost:4200")
                            .AllowAnyMethod()
                            .AllowAnyHeader()
                            .AllowCredentials();
                    });
            });

            services.AddAuthentication(options =>
                {
                    options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                    options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
                })
                .AddJwtBearer(options =>
                {
                    options.Authority = "dev-***.us.auth0.com";
                    options.Audience = "apikey://666fcd34 *****";
                    options.RequireHttpsMetadata = false;
                    options.Events = new JwtBearerEvents
                    {
                        OnAuthenticationFailed = context =>
                        {
                            throw new Exception($"Authentication failed for MetadataAddress {context.Options.MetadataAddress} with exception: {context.Exception}");
                            var logger = context.HttpContext.RequestServices.GetRequiredService<ILoggerFactory>().CreateLogger(nameof(JwtBearerEvents));
                            logger.LogWarning($"Authentication failed for MetadataAddress {context.Options.MetadataAddress} with exception: {context.Exception}");
                            return Task.CompletedTask;
                        }
                    };
                });

            services.AddAuthorization(options =>
            {
                options.AddPolicy("device:read", policy => policy.Requirements.Add(new HasScopeRequirement("device:read", "dev-***.us.auth0.com")));
            });

            services.RegisterDataServices();

            services.AddSingleton<IAuthorizationHandler, HasScopeHandler>();
            services.AddTransient<SelectListService>();
            services.AddTransient<IHttpContextAccessor, HttpContextAccessor>();

            services.AddScoped<HostNameProviderService>();

            services.AddTransient<IGeneralNoteService, GeneralNoteService>();
            services.AddTransient<IDeviceService, DeviceService>();
            services.AddTransient<ICountryService, CountryService>();
            services.AddTransient<IDeviceService, DeviceService>();
            services.AddTransient<IDeviceLoanService, DeviceLoanService>();
            services.AddTransient<DeviceMaintenanceService>();
            services.AddTransient<ICountryPresentationService, CountryPresentationService>();
            services.AddTransient<IDevicePresentationService, DevicePresentationService>();
        }

        // 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();
                app.UseSwagger();
                app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "Equipment.Api v1"));
            }

            app.UseMiddleware<ErrorLoggerMiddleware>();
            app.UseMiddleware<TimedHttpCallMiddleware>();
            app.UseCors("AllowSpecificOrigin");
            app.UseAuthentication();
            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");
            });
        }
    }
}

```

**API Controller:**

```
namespace Equipment.Api.Controllers
{
    using System;
    using System.Collections.Generic;
    using System.Threading.Tasks;
    using Common.DtoModel;
    using Common.Interfaces;
    using Microsoft.AspNetCore.Authorization;
    using Microsoft.AspNetCore.Mvc;

    [ApiController]
    [Route("[controller]")]
    public class DeviceController : ControllerBase
    {
        private readonly IDeviceService _deviceService;

        public DeviceController(IDeviceService deviceService)
        {
            _deviceService = deviceService;
        }

        [Authorize]
        [HttpGet("GetAll")]
        public async Task<IEnumerable<Device>> GetAll()
        {
            return await _deviceService.GetAllAsync();
        }

        [HttpGet]
        public async Task<Device> Get(Guid id)
        {
            return await _deviceService.GetByIdAsync(id);
        }

        [HttpPost]
        public async Task Post([FromBody] Device device)
        {
            await _deviceService.UpdateAsync(device);
        }

        [HttpPut]
        public async Task Put([FromBody] Device device)
        {
            await _deviceService.Insert(device);
        }

    }
}

```

**The error that I get from Chrome Debugger:**

```
{
    "headers": {
        "normalizedNames": {},
        "lazyUpdate": null,
        "headers": {}
    },
    "status": 401,
    "statusText": "OK",
    "url": "https://localhost:44335/device/getall",
    "ok": false,
    "name": "HttpErrorResponse",
    "message": "Http failure response for https://localhost:44335/device/getall: 401 OK",
    "error": null
}

```

**Auth0 Application API Config**  
- Identifier : “apikey://666fcd34\*\*\*\*\*”"  
- Enable RBAC : On  
- Permission: device:read

**Auth0 Application Config**  
Domain: dev-\*\*\* .us.auth0.com  
Client Id: Sk\*\*\*\*\*\*\*\*\*dm  
Application Type : SPA  
Token Endpoint: None  
Grant Type: implicit, AuthorizationCode, RefreshToken

API URL: [http://localhost:62816](http://localhost:62816) / http **s** ://localhost:44335

**Environement**

- Visual Studio 2019 (last update - 16.9.3)
- Windows 10 (last update - 20H2)
- Angular 9.1.14
- .Net Core Framework 5.0

---

<div class="post-metadata">

**Author:** ![dan.woda](https://sea1.discourse-cdn.com/auth0/user_avatar/community.auth0.com/dan.woda/32/18340_2.png) [@dan.woda](https://community.auth0.com/u/dan.woda)\
**Post date:** [April 13, 2021, 4:53pm UTC](https://community.auth0.com/t/angular-net-core-5-api-auth0-http-401/60992/3 "2021-04-13T16:53:56Z")

</div>

Hi @hugodufort,

Will you please print and decode the access token and confirm that the token audience matches the API identifier you are validating for in your .net app?

You can decode and inspect the access token with [JWT.io](http://JWT.io).

If you are having trouble, you can DM me the token and I will take a look.

---

<div class="post-metadata">

**Author:** ![hugodufort](https://sea1.discourse-cdn.com/auth0/user_avatar/community.auth0.com/hugodufort/32/14067_2.png) [@hugodufort](https://community.auth0.com/u/hugodufort)\
**Post date:** [April 13, 2021, 7:42pm UTC](https://community.auth0.com/t/angular-net-core-5-api-auth0-http-401/60992/4 "2021-04-13T19:42:08Z")

</div>

Thanks for your reply, since the application is a SPA, I can’t figure out how to get the Token.  
How to get it when the Grant Type is: Implicit, Authorization Code, Refresh Token?

---

<div class="post-metadata">

**Author:** ![dan.woda](https://sea1.discourse-cdn.com/auth0/user_avatar/community.auth0.com/dan.woda/32/18340_2.png) [@dan.woda](https://community.auth0.com/u/dan.woda)\
**Post date:** [April 13, 2021, 8:02pm UTC](https://community.auth0.com/t/angular-net-core-5-api-auth0-http-401/60992/5 "2021-04-13T20:02:16Z")

</div>

I might be easier just to send me a HAR of the entire transaction.

> **[Generate and Analyze HAR Files](https://auth0.com/docs/troubleshoot/troubleshooting-tools/generate-and-analyze-har-files)**
>
> Learn how to troubleshoot with HAR files and steps to generate a HAR file.

Please DM me the recorded HAR.

---

<div class="post-metadata">

**Author:** ![hugodufort](https://sea1.discourse-cdn.com/auth0/user_avatar/community.auth0.com/hugodufort/32/14067_2.png) [@hugodufort](https://community.auth0.com/u/hugodufort)\
**Post date:** [April 13, 2021, 8:12pm UTC](https://community.auth0.com/t/angular-net-core-5-api-auth0-http-401/60992/6 "2021-04-13T20:12:01Z")

</div>

OK , I’ve created a Test EndPoint application with the “Test” Tab from the EndPoint config page.  
And I have a token,  
The header is:

```
{
  "alg": "RS256",
  "typ": "JWT",
  "kid": "lSUjob6JrpUXVpMNF0aiL"
}

```

the payload is

```
{
  "iss": "https://dev-976r1e2b.us.auth0.com/",
  "sub": "WgWiktEzuBU9jDjnLGnEHrIbjrdkaRDV@clients",
  "aud": "apikey://666fcd34 *****",
  "iat": 1618344383,
  "exp": 1618430783,
  "azp": "WgWiktEzuBU9jDjnLGnEHrIbjrdkaRDV",
  "gty": "client-credentials"
}

```

Are you good with that?

---

<div class="post-metadata">

**Author:** ![dan.woda](https://sea1.discourse-cdn.com/auth0/user_avatar/community.auth0.com/dan.woda/32/18340_2.png) [@dan.woda](https://community.auth0.com/u/dan.woda)\
**Post date:** [April 13, 2021, 8:14pm UTC](https://community.auth0.com/t/angular-net-core-5-api-auth0-http-401/60992/7 "2021-04-13T20:14:41Z")

</div>

We need to see the token requested by your SPA. I am specifically looking for the aud claim. It looks like you are requesting a token in your SPA with a different audience than what your API is expecting.

---

<div class="post-metadata">

**Author:** ![hugodufort](https://sea1.discourse-cdn.com/auth0/user_avatar/community.auth0.com/hugodufort/32/14067_2.png) [@hugodufort](https://community.auth0.com/u/hugodufort)\
**Post date:** [April 13, 2021, 8:20pm UTC](https://community.auth0.com/t/angular-net-core-5-api-auth0-http-401/60992/8 "2021-04-13T20:20:48Z")

</div>

I sent you the HAR file in DM

---

<div class="post-metadata">

**Author:** ![system](https://global.discourse-cdn.com/auth0/original/3X/b/5/b560f266932fcce5d57f09a6595bd50518cae3f3.jpeg) [@system](https://community.auth0.com/u/system)\
**Post date:** [June 1, 2021, 5:04pm UTC](https://community.auth0.com/t/angular-net-core-5-api-auth0-http-401/60992/9 "2021-06-01T17:04:12Z")

</div>

This topic was automatically closed 15 days after the last reply. New replies are no longer allowed.
