简体   繁体   中英

Angular POST and .NET Core WEB Api - 401 Unauthorized error / CORS

I have separate projects for front-end (Angular) and back-end (.NET Core WEB Api). I have been setup the CORS as well the windows AD authentification. All that is working well for GET calls, but I am having issues with the POST. I am getting following error.

OPTIONS http://localhost:50000/api/data/Update 401 (Unauthorized)
Access to XMLHttpRequest at 'http://localhost:50000/api/data/Update' from origin 'http://localhost:4200' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Error: Http failure response for http://localhost:50000/api/data/Update: 0 Unknown Error

user.component.ts

update(data: NgForm) {
if (data.form.valid) {
  this.service.update(data.value)
    .subscribe(
      res => {
        console.log('Result: ' + res);
      },
      err => {
        console.log('Error: ' + err.message);
    });
  }
}

service.ts

headerOptions = new HttpHeaders({ 'Content-Type': 'application/x-www-form-urlencoded', 'Access- 
Control-Allow-Origin': '*' });

update(data: Form) {
  return this.http.post(this.apiUrl + '/data/Update', data, { headers: this.headerOptions });
}

Controller

[HttpPost("[action]")]
public string Update([FromForm] User data)
  {
    if (data != null)
  {
    return "Ok";
  }
    else
  {
    return "Data is null";
  }
}

CORS extension

    public static void ConfigureCors(this IServiceCollection services)
    {
        services.AddCors(options =>
        {
            options.AddPolicy("CorsPolicy", 
                builder => builder
                .WithOrigins("http://localhost:4200")
                .AllowAnyMethod()
                .AllowAnyHeader()
                .AllowCredentials());
        });
    }

I also have the interceptor inside Angular which is sending "withCredentials: true" for all calls.

Have in mind that all my GET calls are working without issues, I only have problems with the POST. If I change the method on Angular side from POST to GET, the Update method from back-end is getting called without issues...

I was able to hit my controller and POST data after I did following changes:

  1. Changed controller attribute from "FromForm" to "FromBody" (thanks to Daniel note about it).
  2. Changed angular post method to the following

     headerOptions = new HttpHeaders({ 'Content-Type': 'application/json' }); update(data) { return this.http.post(this.apiUrl + '/data/Update', JSON.stringify(data), { headers: this.headerOptions }); }
  3. Set "anonymousAuthentication: true" inside my launchSettings.json.

  4. On this stage I had an issue because my user was null on application start, so I had to implement a new middleware found on this question ntlm anon in order to handle non-authenticated user on app start.

  5. Call middleware inside Configure (Startup.cs), just pay attention on the order. Here is mine:

    app.UseCors("CorsPolicy");
    app.UseAnonMiddleware();
    app.UseAdMiddleware();
    app.UseMvc();

And thats it.

Different ports are exactly the same as different applications, therefore your WebApi should allow CORS like

 [EnableCors(origins: "http://localhost:4200", headers: "*", methods: "*")]
    public class TestController : ApiController
    {
        // Controller methods not shown...
    }

However, if this is the same application and all you want is that all of the work through the same port then what I think you need to do is:

Add Microsoft.AspNetCore.SpaServices.Extensions nuget package.

And then configure in you Startup.cs the Angular Cli like:

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

app.UseMvc(routes =>
 {
    routes.MapRoute(name: "default",emplate: "{controller}/{action=Index}/{id?}");
            });

            app.UseSpa(spa =>
            {
                spa.Options.SourcePath = "ClientApp";

                if (env.IsDevelopment())
                {
                    spa.UseAngularCliServer(npmScript: "start");
                }
            });

Important :

To learn more about options for serving an Angular SPA from ASP.NET Core, see https://go.microsoft.com/fwlink/?linkid=864501

This allows you to have if you want angular running on separate port or the same port as your .net core app.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM