Enabling CORS in .Net Core Web API

 

Cross-Origin Resource Sharing (CORS)

Browser security prevents a web page from making requests to a different domain than the one that served the web page. This restriction is called the same-origin policy. The same-origin policy prevents a malicious site from reading sensitive data from another site.

Cross-Origin Resource Sharing (CORS) is an HTTP-header based mechanism that allows a server to indicate any origins (domain, scheme, or port) other than its own from which a browser should permit loading resources

Cross Origin Resource Sharing (CORS):

  • Is a W3C standard that allows a server to relax the same-origin policy.
  • Is not a security feature, CORS relaxes security. An API is not safer by allowing CORS. For more information, see How CORS works.
  • Allows a server to explicitly allow some cross-origin requests while rejecting others.
  • Is safer and more flexible than earlier techniques, such as JSONP.
In this example - we have an API endpoint that gives the list of Employee Data


If we try to consume the same API from an Ajax call (Refer privacy page for this implementation - 
http://localhost:5176/Home/Privacy), we get the below error.


Here the web application is running on the host http://localhost:5176/ which is trying to call an API from http://localhost:5157/ (not from same domain) and that's why it is not working.

To make it working, we need to Enable CORS at the API layer (it means we are relaxing the rules at API layer to allow access from a defined source)

There are 2 changes required in the Web API layer to achieve this.

builder.Services.AddCors(options =>
{
    options.AddDefaultPolicy(builder =>
    {
        builder.WithOrigins("http://localhost:5176")  //we should never allow * here because that is a big security risk
        .WithHeaders("content-type");
    });
});

and

app.UseCors();

If we try to access the API using JQuery from the web application - it should work fine.
  • An important point to observe here is that with origins takes an array of source, so we can provide multiple URLs here and the API will work from all requests coming from any of these sources.
  • We can also use WithHeaders (to provide the header name) and WithMethods (to specify Http method names) to control what is allowed or not
Instead of using the default policy of CORS - we can also create custom polices and use that

options.AddPolicy("SpecificOrigin", builder =>
                {
                    builder.WithOrigins("http://localhost:2020")
                        .WithHeaders("Authorization");
                });

In this case - we should use app.UseCors("SpecificOrigin"); instead of app.UseCors();

We can also use [EnableCors] or [EnableCors(PolicyName ="SpecificOrigin")] at the controller or action level for more control. Writing this at control or action level will override the default behavior.

We can also use [DisableCors] - at controller or action level which will ensure that these methods are not accessible from cross origin.


Preflight requests

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

  • The request method is GET, HEAD, or POST.
  • The app doesn't set request headers other than AcceptAccept-LanguageContent-LanguageContent-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
Browser makes a request of OPTIONS type to check the value of Access-Control-Allow-Origin (This call happens automatically before the actual API call ). If it gets a 204 response with the correct value in Access-Control-Allow-Origin - then only it makes the actual API call.

Reference Link:

GitHub URL


Comments

Popular posts from this blog

Publish .Net Core Web API to Linux Host

Entity Relationship Using EF Core Code First Approach

Web API Using EF Core