1

I am using .NET Core 2.1. I have configured Startup.cs as follow:

public class Startup
{   
     public static IConfiguration Configuration { get; private set; }

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


     public void ConfigureServices(IServiceCollection services)
     {
         services.AddCors();
         services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
     }

     public void Configure(IApplicationBuilder app, IHostingEnvironment env)
     {
         app.UseCors(builder => builder.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());

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

         app.UseMvc();
     }
 }

Web API is deployed on linux machine. GET and POST methods are working fine. When I try to call PUT or DELETE this message is being generated in Chroome console.

Access to XMLHttpRequest at 'http://IP' from origin 'http://IP' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

Initially Kestrel was listing on 50001 beacuse SSL certificate was present. I configured Kestrel in appsettings.json to listen only on 5000. So now its only listing on 5000.

appsettings.json

{
    "Kestrel": {
        "EndPoints": {
            "Http": {
                "Url": "http://localhost:5000"
            }
        }
    }
}

I've tried almost every answer given in this thread How to enable CORS in ASP.net Core WebAPI

None of them worked in my case.

Origin is my localhost and Web API is on Live IP.

EDIT 1

Preflight (OPTIONS) Response Headers

HTTP/1.1 204 No Content
Server: nginx/1.14.0 (Ubuntu)
Date: Sat, 25 Apr 2020 18:50:50 GMT
Connection: keep-alive
Access-Control-Allow-Headers: authtoken,authuser,content-type
Access-Control-Allow-Methods: PUT
Access-Control-Allow-Origin: *

Preflight (OPTIONS) Request Headers

OPTIONS /Foo/Controller HTTP/1.1
Host: MY LINUX Machine Live IP
Connection: keep-alive
Access-Control-Request-Method: PUT
Origin: http://localhost:8080
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.122 Safari/537.36
Access-Control-Request-Headers: authtoken,authuser,content-type
Accept: */*
Referer: http://localhost:8080/xyz
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9

Actual Request (Request Headers)

PUT /Foo/Controller HTTP/1.1
Host: Linux IP
Connection: keep-alive
Content-Length: 63
Accept: application/json, text/javascript, */*; q=0.01
Origin: http://localhost:8080
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.122 Safari/537.36
Content-Type: application/json
Referer: http://localhost:8080/xyz
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9

Actual Request (Response Headers)

HTTP/1.1 500 Internal Server Error
Content-Type: text/html
Content-Length: 225
Connection: Close
Afnan Ahmad
  • 2,492
  • 4
  • 24
  • 44
  • 1
    Check if your server is throwing an exception. This often shows up as a CORS error, but it's really down to the server errors. – Kirk Larkin Apr 25 '20 at 19:58
  • @Kirk Larkin can it be a server error if its running in development mode perfectly ? – Afnan Ahmad Apr 25 '20 at 20:14
  • Of course. Perhaps there's a different database being used, different permissions to write files, etc. There could be _many_ differences between development and production. Check the response in the developer tools - see if it's returning a 500 status code, for example. – Kirk Larkin Apr 25 '20 at 20:16
  • @KirkLarkin Yeah I agree with you. But I am seeing 'No 'Access-Control-Allow-Origin' header is present on the requested resource.' after preflight request. Let me update my question. – Afnan Ahmad Apr 25 '20 at 20:18
  • Is there an actual response that comes back from the actual request you've shown? What does that look like? – Kirk Larkin Apr 25 '20 at 20:21
  • @KirkLarkin Yes preflight is successful. I think I am missing some thing very common. `'No 'Access-Control-Allow-Origin' header is present on the requested resource.'` This is related to preflight or actual request ? I have mentioned pre flight response and request header in my question and it seems like that prefight was ok. So is this error from actual request as I have no `Access-Control-Allow-Origin` in actual request headers ad I mentioned in question. – Afnan Ahmad Apr 25 '20 at 20:24
  • It looks like it's related to the _actual_ request. You should be able to see it in the developer tools. The response comes back, but the browser blocks access to it from the XHR. It'll still be visible in the developer tools, as a response to the _actual_ request you've shown. – Kirk Larkin Apr 25 '20 at 20:27
  • @KirkLarkin I have updated both in my question. Actual request, request headers and actual request repsonse headers. – Afnan Ahmad Apr 25 '20 at 20:27
  • Yep, there you go. Your server threw an error and returned a 500. CORS headers won't be set in that case. Have a look at the server logs to try and find out why it's throwing an error. – Kirk Larkin Apr 25 '20 at 20:27
  • @KirkLarkin Yup I agree CORS headers are not being set because of 500. It means CORs is working fine or do I have to set anyting in nginx ? – Afnan Ahmad Apr 25 '20 at 20:29

4 Answers4

3

Resolved by adding the following settings to web.config

[1]: https://i.stack.imgur.com/Lyeph.png

2

.NET Core enables the WebDAVModule, which disables PUT and DELETE requests by default. So, to solve the issue, I ended up disabling WebDAV in the whole application, by adding these lines to the auto-generated web.config:

<system.webServer></system.webServer>

laxmannegi
  • 21
  • 1
1

Tried below on .net core web API

Yes, you can add <modules runAllManagedModulesForAllRequests="false"> <remove name="WebDAVModule" /> </modules>

inside <system.webServer> tag of your auto-generated web.config file (config file is creating once you hosted the API)

screen

Please note below for CORS in your .net core API's startup class

--in ConfigureServices Method

 services.AddCors();
 services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

--in Configure Method

app.UseCors(Options =>
                   Options.WithOrigins("your client URL")
                   .AllowAnyMethod()
                   .AllowAnyHeader()
                  
              );


            app.UseAuthentication();  //for JWT
            app.UseMvc();
Francois du Plessis
  • 2,143
  • 2
  • 17
  • 17
0

With the specific failures being on the PUT and DELETE calls, it sounds like you're still running into issues with preflight requests

Per https://learn.microsoft.com/en-us/aspnet/core/security/cors?view=aspnetcore-2.1#preflight-requests-1 :

Preflight requests For some CORS requests, the browser sends an additional request before making the actual request. This request is called a preflight request. The browser can skip the preflight request if the following conditions are true:

  • The request method is GET, HEAD, or POST.
  • The app doesn't set request headers other than Accept, Accept-Language, Content-Language, Content-Type, or Last-Event-ID.
  • The Content-Type header, if set, has one of the following values:
    • application/x-www-form-urlencoded
    • multipart/form-data
    • text/plain

It's difficult to troubleshoot specifically with what you have above alone without knowing whether there's anything like nginx or some other reverse proxy between Kestrel and the web that may be impacting headers. During testing, this article from Rick Strahl also presents a good reminder during local or non-cross origin testing:

https://weblog.west-wind.com/posts/2016/sep/26/aspnet-core-and-cors-gotchas#Watch-out-for-testing-CORS-without-Cross-Domain!

CORS headers are only sent on cross domain requests and the ASP.NET CORS module is smart enough to detect whether a same domain request is firing and if it is, doesn't send the headers.

When checking that error out in Chrome, make sure you're able to take a look at the calls being made and confirm any preflight OPTIONS calls contain the headers being looked for. This StackOverflow link describes enabling showing the OPTIONS requests in debug:

https://stackoverflow.com/a/57669710/13374279

Adam
  • 3,339
  • 1
  • 10
  • 15
  • I have two extra headers other than Content-Type and also Content-Type is application/json. So it means I need to look into preflight. Plus I do have nginx. – Afnan Ahmad Apr 25 '20 at 18:54
  • Is there anything we need to do in nginx for this purpose ? – Afnan Ahmad Apr 25 '20 at 18:56
  • I've included preflight request and response headers too. – Afnan Ahmad Apr 25 '20 at 19:23
  • Based on your additions above with the 500 error, you should be checking the debug logs for your hosted API to find out what is throwing the error there, as Kirk suggested. If you're not logging errors to a visible console or to disk, that would be your next step. It's likely something on the other end of your call is throwing an exception of some kind that you are not catching and dealing with. – Adam Apr 26 '20 at 17:49