'Visual studio's ASP.NET core with angular template always returns 401

I'm using Microsoft Visual Studio Community 2019 Version 16.10.2. I created an ASP.net core 5 project from their template "ASP.net core with Angular" with Authentication checked. But Every time I request an API Method marked with the attribute [Authorize] I get 401.

Their template was supposed to work with no problem but I got some trouble logging in. I fixed them but, the only problem I can't figure out how to fix is the 401 code returned ASP.

I read the doc several times but I could not find any useful information.

The thing is: I can create accounts and login with no problem. When I login, the server returns the token. From the Angular app it shows the name of the logged-in user. But when to access an [Authorize] controller it returns 404.

Here is the link of the project I pushed to github for better debugging.

Here is the startup code:

public void ConfigureServices(IServiceCollection services)
        {
            services.AddDbContext<ApplicationDbContext>(options =>
                options.UseSqlServer(
                    Configuration.GetConnectionString("DefaultConnection")));

            services.AddDatabaseDeveloperPageExceptionFilter();

            services.AddDefaultIdentity<ApplicationUser>(options => options.SignIn.RequireConfirmedAccount = true)
                .AddEntityFrameworkStores<ApplicationDbContext>();

            services.AddIdentityServer()
                .AddApiAuthorization<ApplicationUser, ApplicationDbContext>(op =>
                {
                    // I added these lines because I was getting the error "Error: Client Angular_identity_test is not allowed access to scope Angular."
                    op.Clients[0].AllowedScopes = new List<string> { "Angular", "identity", "testAPI" };

                    op.ApiScopes = new Microsoft.AspNetCore.ApiAuthorization.IdentityServer.ApiScopeCollection(new List<ApiScope> { new ApiScope("Angular"), new ApiScope("identity"), new ApiScope("testAPI") });
                    op.ApiResources.AddApiResource("Angular", conf => conf.WithScopes(new string[] { "Angular", "identity", "testAPI" }));
                    op.ApiResources.AddApiResource("identity", conf => conf.WithScopes(new string[] { "Angular", "identity", "testAPI" }));
                    op.ApiResources.AddApiResource("testAPI", conf => conf.WithScopes(new string[] { "Angular", "identity", "testAPI" }));
                });

            services.AddAuthentication()
                .AddIdentityServerJwt();
            services.AddControllersWithViews();
            services.AddRazorPages();
            // In production, the Angular files will be served from this directory
            services.AddSpaStaticFiles(configuration =>
            {
                configuration.RootPath = "ClientApp/dist";
            });
        }

// In public void Configure(IApplicationBuilder app, IWebHostEnvironment env)

            app.UseHttpsRedirection();
            app.UseStaticFiles();
            if (!env.IsDevelopment())
            {
                app.UseSpaStaticFiles();
            }

            app.UseRouting();

            // I added this line because some people say that fixed their problems.
            app.UseCors(x => x
            .AllowAnyOrigin()
            .AllowAnyMethod()
            .AllowAnyHeader());

            app.UseAuthentication();
            app.UseIdentityServer();
            app.UseAuthorization();
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller}/{action=Index}/{id?}");
                endpoints.MapRazorPages();
            });

            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");
                }
            });

In the appsettings.json there is:

"IdentityServer": {
    "Clients": {
      "Angular_identity_test": {
        "Profile": "IdentityServerSPA"
      }
    }
  }

And the controller that keeps return 401:

[Authorize()]
    [ApiController]
    [Route("[controller]")]
    public class WeatherForecastController : ControllerBase
    {
        private static readonly string[] Summaries = new[]
        {
            "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
        };

        private readonly ILogger<WeatherForecastController> _logger;

        public WeatherForecastController(ILogger<WeatherForecastController> logger)
        {
            _logger = logger;
        }

        [HttpGet]
        public IEnumerable<WeatherForecast> Get()
        {
            var rng = new Random();
            return Enumerable.Range(1, 5).Select(index => new WeatherForecast
            {
                Date = DateTime.Now.AddDays(index),
                TemperatureC = rng.Next(-20, 55),
                Summary = Summaries[rng.Next(Summaries.Length)]
            })
            .ToArray();
        }


Solution 1:[1]

So you say, But when to access a [Authorize] controller it returns 404. use this below code, instead of [Authorize].

[Authorize(AuthenticationSchemes = "Bearer")]

It will resolve your issue.

UPDATE

Use this below code and i assume that your Token is place of appsettings.development.json file. like "TokenKey":"super secret key",

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
                 .AddJwtBearer(options => {
                     
                     options.TokenValidationParameters=new TokenValidationParameters
                     {
                         
                          ValidateIssuerSigningKey=true,
                          IssuerSigningKey=new SymmetricSecurityKey( Encoding.UTF8.GetBytes(config["TokenKey"]) ),
                          ValidateIssuer=false,
                          ValidateAudience=false
                     };

                 });

Hope it will resolve your issue.

Solution 2:[2]

This will be a proxy issue. In your CLIENTAPP go to the proxy.conf.js and add your controllers route into the PROXY_CONFIG->context array (like "/weatherforecast" is). Then restart your application. You don't need to change .NET Core middleware or services.

UPDATE

I added this DI BASE_URL into my service constructor and it works fine now.

constructor(private http: HttpClient, @Inject('BASE_URL') private bUrl: string) {
    this.baseUrl = bUrl + "api/v1/items"; // my endpoint
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2