Jesse Seger Jesse Seger - 1 year ago 114
C# Question

ASP.NET Web API CORS not working with AngularJS

I have an ASP.NET Web API running locally on some port and I have an angularjs app running on 8080. I want to access the api from the client.

I can successfully login and register my application because in my OAuthAuthorizationProvider explicitly sets the repsonse headers in the /Token endpoint.

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


That's good. However, my other API methods do not seem to work. In my WebApiCongig.Register, I enable CORS and I add the EnableCors Attribute to my controllers to allow all origins, all headers, and all methods. I can set a break point in my get method on the controller and it gets hit just fine. Here is what I found watching the Network tab in chrome.

2 requests are are sent to the same api method. One method type OPTIONS and one with method type GET. The OPTIONS request header includes these two lines


Access-Control-Request-Headers:accept, authorization

Access-Control-Request-Method:GET


And the response includes these lines


Access-Control-Allow-Headers:authorization

Access-Control-Allow-Origin:*


However, the GET method request looks quite different. It returns ok with a status code of 200, but it does not inlcude and access control headers in the request or response. And like I said, it hits the API just fine. I can even do a POST and save to the database, but the client complains about the response!!

I've looked at every single SO question and tried every combination of enabling cors. I'm using Microsoft.AspNet.Cors version 5.2.2. I'm' using AngularJS version 1.3.8. I'm also using the $resource service instead of $http which doesn't seem to make a difference either.

If I can provide more information, please let me know.

BTW, I can access the Web API using Fiddler and/or Postman by simply including the Bearer token.

Answer Source

This ended up being a simple fix. Simple, but it still doesn't take away from the bruises on my forehead. It seems like the more simple, the more frustrating.

I created my own custom cors policy provider attribute.

public class CorsPolicyProvider : Attribute, ICorsPolicyProvider
{
    private CorsPolicy _policy;

    public CorsPolicyProvider()
    {
        // Create a CORS policy.
        _policy = new CorsPolicy
        {
            AllowAnyMethod = true,
            AllowAnyHeader = true,
            AllowAnyOrigin = true
        };

       // Magic line right here
        _policy.Origins.Add("*");

    }

    public Task<CorsPolicy> GetCorsPolicyAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        return Task.FromResult(_policy);
    }
}

I played around with this for hours. Everything should work right?? I mean the EnableCors attribute should work too?? But it didn't. So I finally added the line above to explicitly add the origin to the policy. BAM!! It worked like magic. To use this just add the attribute to your api class or method you want to allow.

[Authorize]
[RoutePrefix("api/LicenseFiles")]
[CorsPolicyProvider]
//[EnableCors(origins: "*", headers: "*", methods: "*")] does not work!!!!!  at least I couldn't get it to work
public class MyController : ApiController
{
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download