'.Net 6 Angular and Authentication 404 error

I've been upgrading a project from angular 11 .net 3.1 to .net 6 angular 13

I have an issue accessing the controllers from the httpclient which returns a 404 error, I know the modal has changed to new minimal hosting model, however it also states that the Generic model is still fully supported.

A push in the right direction will be greatly appreciated.

The spa app starts, and displays the web page, however as soon as it trys to call the .net controller it returns a 404 error. I have hardcoded the uri, but still get the same error.

postman returns the expected 401 error due to not being authorized.

everything was working as it should before the upgrade.

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILog logger) {

      if (env.IsDevelopment()) {
        app.UseDeveloperExceptionPage();

        app.UseExceptionHandler(exceptionHandlerApp =>
        {
          exceptionHandlerApp.Run(async context =>
          {
            context.Response.StatusCode = StatusCodes.Status500InternalServerError;

            // using static System.Net.Mime.MediaTypeNames;
            context.Response.ContentType = Text.Plain;

            await context.Response.WriteAsync("An exception was thrown.");

            var exceptionHandlerPathFeature =
                context.Features.Get<IExceptionHandlerPathFeature>();

            if (exceptionHandlerPathFeature?.Error is FileNotFoundException) {
              await context.Response.WriteAsync(" The file was not found.");
            }

            if (exceptionHandlerPathFeature?.Path == "/") {
              await context.Response.WriteAsync(" Page: Home.");
            }
          });
        });

      }
      else {

        app.UseExceptionHandler("/Error");
        app.UseHsts();

      }
      app.ConfigureExceptionHandler(logger);

      app.UseHttpsRedirection();

      app.UseStaticFiles();
      app.UseSpaStaticFiles();

      app.UseRouting();
      app.UseCors();
      app.UseSecurityHeaders(env.IsDevelopment());


      app.UseAuthentication();
      app.UseAuthorization();

      app.UseEndpoints(endpoints => {
        endpoints.MapHub<SignalrCartHub>("/signalrCartHub");
        endpoints.MapControllers();
      });



      app.UseSpa(spa => {
        // spa.ApplicationBuilder.UseCors(ApplicationCors);
        spa.Options.SourcePath = "ClientApp";
        spa.Options.StartupTimeout = new TimeSpan(0, 5, 0);

        if (env.IsDevelopment()) {
          spa.UseAngularCliServer(npmScript: "start");
          //spa.UseProxyToSpaDevelopmentServer("http://localhost:5100");
        }

      });



    }

 public void ConfigureServices(IServiceCollection services) {
     
      services.Configure<IISOptions>(iis => iis.ForwardClientCertificate = false);
      services.AddSignalR();

      services.AddRazorPages().AddMvcOptions(options => {
        var policy = new AuthorizationPolicyBuilder()
            .RequireAuthenticatedUser()
            .Build();
        options.Filters.Add(new AuthorizeFilter(policy));
      }).AddNewtonsoftJson();

      services.AddAuthorization(options => {
        options.FallbackPolicy = new AuthorizationPolicyBuilder()
        .RequireAuthenticatedUser()
        .Build();
      });


      services.AddMvc(options => {
        var policy = new AuthorizationPolicyBuilder()
            .RequireAuthenticatedUser()
            .Build();

        options.Filters.Add(new AuthorizeFilter(policy));
      }).AddNewtonsoftJson(options => { options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; });


      services.AddCors(options =>
           options.AddPolicy(ApplicationCors, policy => {
             string[] origins = Configuration.GetSection("Cors.Origins").Get<string[]>();
             policy.WithOrigins(origins).SetIsOriginAllowedToAllowWildcardSubdomains();
             policy.AllowAnyMethod();
             policy.AllowAnyHeader();
           }));

      services.AddSpaStaticFiles(x => x.RootPath = "ClientApp/dist");

      services.AddHttpClient();
      services.AddAutoMapper(typeof(Startup));



      AddAuthentication(services);

      var endpointSection = Configuration.GetSection("Endpoints");
      services.Configure<AppSettings>(endpointSection);

      var connectionInfo = SetDatabase(services);
      connectionInfo.DevMode = isDevMode();

      AddDependancyInjection(services, connectionInfo);
    }


    private void AddAuthentication(IServiceCollection services) {

      bool proxy = Configuration.GetValue<bool>("Proxy:Enabled");
      services.AddAuthentication(x => {
        x.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
        x.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
      })
          .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, cookie => {
            cookie.SessionStore = new MemoryCacheTicketStore();
            cookie.ExpireTimeSpan = new TimeSpan(0, 15, 0);

          })
          .AddOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme, oidc => {
            oidc.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
            // oidc.ReturnUrlParameter = Configuration["Authentication:Return"];
            oidc.Authority = Configuration["Authentication:Authority"];
            oidc.ResponseType = Configuration["Authentication:ResponseType"];
            oidc.ClientId = Configuration["Authentication:ClientId"];
            string secret = Configuration["Authentication:ClientSecret"];
            oidc.AuthenticationMethod = OpenIdConnectRedirectBehavior.FormPost;

            if (secret == null) throw new ArgumentNullException(nameof(secret));

            oidc.ClientSecret = secret;
            oidc.Scope.Clear();
            oidc.Scope.Add("openid");
            oidc.Scope.Add("profile");
            oidc.Scope.Add("email");
            oidc.Scope.Add("phone");
            oidc.Scope.Add("applications");
            oidc.Scope.Add("permissions");
            oidc.SaveTokens = true;
            oidc.GetClaimsFromUserInfoEndpoint = true;
            oidc.AccessDeniedPath = new PathString("/errorSignOn/index");
            oidc.TokenValidationParameters = new TokenValidationParameters {
              NameClaimType = JwtClaimTypes.Name,
              RoleClaimType = JwtClaimTypes.Role
            };

           

            OnAuthenticationFailed(oidc);
            OnRemoteFailure(oidc);
            OnRedirectToIdentityProvider(oidc);
            //OnUserInformationReceived(services, oidc);
            BackchannelHttpHandler(oidc);
          });
    }


[Route("api/[controller]")]
  [ApiController]
  [Authorize]
  
  public class TenantController : ControllerBase {
...
    [HttpGet]
    [Route("getappdetails")]
    public async Task<IActionResult> GetAppDetails() {
       ...
    }
}

Error

Failed to load resource: the server responded with a status of 404 () .main.js:1 ERROR HTTP:::

Cannot GET /api/Tenant/getuserdetails

headers: wo {normalizedNames: Map(0), lazyUpdate: null, lazyInit: ƒ}

message: "Http failure response for https://localhost:5001/api/Tenant/getuserdetails: 404

url: "https://localhost:5001/api/Tenant/getuserdetails"



Solution 1:[1]

I had an old ref to

PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.2.0" 

removing it fixed the issue.

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 Anthony