24

there are 100s of question on CORS on web-api, and on how to enable CORS, there is a different answer each one provides. I am so confused and dont know which answer is correct. And the problem is none of the answers actually explains it point wise, what each line of code does, so that I can understand and solve my problem rather than copy-pasting the code.

anyways, the question is: I am using asp.net web api 2 using owin. And i need to enable CORS. how do I do it? There is cors settings for OWIN

  application.UseCors(CorsOptions.AllowAll);

and there is cors settings for asp.net web api

   var cors = new EnableCorsAttribute("*", "*", "*", "*");
   config.EnableCors(cors);

which one should I use given I am not using OAUTH (I am specifying this because answers on SO differ on when we use OAUTH v/s when we dont use it).

Do i need to enable CORS for both OWIN & WEB-API or only for one of them. There is issue if both are enabled, read here

It would be really helpful if someone can explain me the difference between

  1. OWIN CORS
  2. WEB API CORS
  3. CORS with OAUTH using OWIN/WEBAPI

Also there are answers for self-hosted web api against owin hosted web-api, which further adds to the confution :(, sorry for the rant

harishr
  • 17,807
  • 9
  • 78
  • 125
  • Agreed, sure would be swell if someone had an explanation without being vague. – Nicholi Jun 08 '15 at 20:09
  • 1
    I am still looking for an answer.. the answers given are incomplete and not to the point. I am not looking for how to do it, that is there is so many other answers – harishr Aug 11 '15 at 03:30

2 Answers2

10

You are supposed to use Web API's CORS if you need CORS applied to your API Controllers. For everything else (like a token service) you're stuck with having to use Owin.Cors.

If you end up using both, you'll need to make sure they don't overlap and apply CORS twice to the same request.

Web API 2.2 makes it easy to enable CORS by providing the EnableCorsAttribute.

Basic Usage

[EnableCors("*", "*", "*")]
public class ResourcesController : ApiController
{
    ...

Attribute definition

[AttributeUsageAttribute(AttributeTargets.Class|AttributeTargets.Method, AllowMultiple = false)]
public EnableCorsAttribute(
    string origins,
    string headers,
    string methods
)

To enable CORS globally use

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        var cors = new EnableCorsAttribute("www.example.com", "*", "*");
        config.EnableCors(cors);
        // ...
    }
}

You will also need to install the CORS package from nuget

Install-Package Microsoft.AspNet.WebApi.Cors
Mihai Dinculescu
  • 19,743
  • 8
  • 55
  • 70
  • I know how to enable cors on web-api, what i want to know is, difference between web-api and owin cors, which to use when. its not about how/where to enable it.... – harishr Dec 05 '14 at 08:57
  • Web API's CORS supports controllers only, for everything else you need to use Owin.Cors. – Mihai Dinculescu Dec 05 '14 at 08:59
  • 1
    what is `everything else` – harishr Dec 05 '14 at 09:00
  • A token service for security is one example. That's not under a Controller. – Mihai Dinculescu Dec 05 '14 at 09:01
  • can you please update your answer, remove how/where to apply it - write about the difference between the CORS. thanks for the answer – harishr Dec 05 '14 at 09:07
  • I have updated it. However I would rather not remove stuff because someone else might find it useful. – Mihai Dinculescu Dec 05 '14 at 09:17
  • 3
    Why not? It answers the question and provides some extra information. – Mihai Dinculescu Dec 05 '14 at 09:48
  • I currently have a Web site accessing a Web API project which is ONLY explicitly configured using app.UseCors(CorsOptions.AllowAll). The website is working as expected, so I'm a bit confused how to correlate this comment with the behavior I'm seeing. What a confusing API. – Derek Greer Feb 21 '15 at 00:28
  • The part I don't get about this is WHY I can't use OWIN Cors. Isn't OWIN supposed to be another layer under Web API? Can you maybe elaborate on that? Thanks anyway - best answer to the problem I've seen so far. – mattanja Jun 17 '15 at 07:50
  • From what I see if you use OWIN the `[EnableCors]` attribute doesn't appear to work when added to API controllers. And app.UseCors() doesn't really have options for per controller/request CORS enabling - only global config. – Rick Strahl Apr 12 '18 at 04:51
3

There is a way to fix this. Since OWIN and ASP.NET.CORS libraries are working simultaneously. Owin token or authentication method needs to be configured to enable CORS separately from all other API controllers.

Fist thing first, don't use cors with Owin in Startup.cs :

public void Configuration(IAppBuilder app)
{
    //app.UseCors(CorsOptions.AllowAll);

Find GrantResourceOwnerCredentials method and add Access-Control-Allow-Origin to context so when it returns a call after authentication is completed that browser finds the header and accepts it.

public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
        context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "http://localhost" });

Now install Microsoft.AspNet.WebApi.Cors package from Nuget to your webapi project, and add this to Register method

public static void Register(HttpConfiguration config)
{
        var cors = new EnableCorsAttribute("http://localhost, ", "accept,accesstoken,authorization,cache-control,pragma,content-type,origin", "GET,PUT,POST,DELETE,TRACE,HEAD,OPTIONS");

        config.EnableCors(cors);

Worked for me.

Dado Kljuco
  • 201
  • 2
  • 3