WebAPI中的CORS问题

I am having a simple webapi project with default controllers. I need to access the same values from a html page using ajax request.

Requirements:

  1. Get the token using token method
  2. Pass the token and get the values

Client Side:

The following is my html page which have 2 buttons. First to get the token and manually i updated the header and get the values using second button.

<html>
<head>
    <script src="https://code.jquery.com/jquery-3.2.1.min.js" integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4="
        crossorigin="anonymous"></script>
    <script type="text/javascript">
        $(document).ready(function () {
            $("#btnToken").click(function () {
                var loginData = {
                    grant_type: 'password',
                    username: 'user1@gmail.com',
                    password: 'MyPassword'
                };

                $.ajax({
                    type: 'POST',
                    url: "http://172.16.2.19:8080/Token",
                    datatype: 'json',
                    data: loginData,
                    success: function (result) {
                        alert(JSON.stringify(result));
                        console.log(JSON.stringify(result));
                    },
                    error: function (error) {
                        alert(JSON.stringify(error));
                    }
                });
            });

            function setHeader(xhr) {
                xhr.setRequestHeader('Access-Control-Allow-Origin', '*');
                xhr.setRequestHeader('Authorization', 'bearer 2wj036uRh7i2DpGAhzNOHuxb1TZcRWVkq_xU3mKGh6e4sO4hdwqaoJLeAAf_hoQewwYxnauUyFXev15oLOybwGDm-KDm-6TXvOSnby-7zYkN7UxNgHlna00hfure3VLYhPclZrQT591qWtH9oeIjc3AyXwJE7N_qhfZxvJKPUp5lTgzVJ9SBbTBOlyKnirUvJxwIrEwKABoNuRW6PbveTGs9i4osCI19mtkG53XB87-g2nwiWu2d2aw12WlT9ShFgf70cDgJMh84KY9eG4Mn9I1EJ2SgZI_i1CSoHktx5W6L8NbZqfv-Nd8qb_tjcw_eIJxZk7RSIDF2p42nVnUNXWJSivgcxNKaTr0KTlmK7PPYLtyyWNiIejZHDlXyBexy_Rmases9TGkIT5h1cpF8E3VNg7zMYCMAflJDYH_0Lj0siQ4QfNAYKB0D3hreEd3qW13YEpWcsGaR2uBI5Qc1l3N44Fyc_d-zLJP_lX8jhYE');
            }

            $("#btnData").click(function () {

                $.ajax({
                    type: 'GET',
                    url: "http://172.16.2.19:8080/api/values",
                    content_type: 'application/json; charset=utf-8',
                    beforeSend: setHeader,
                    success: function (result) {
                        alert(JSON.stringify(result));
                        console.log(JSON.stringify(result));
                    },
                    error: function (error) {
                        alert(JSON.stringify(error));
                    }
                });
            });
        });
    </script>
</head>
<body>
    <button id="btnToken" name="btnToken">Token</button>
    <button id="btnData" name="btnData">Data</button>
</html>

Serverside:

I enabled CORS in the code and have the following in my apiconfig

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        // Web API configuration and services
        var cors = new EnableCorsAttribute("*", "*", "*");
        config.EnableCors(cors);

        // Configure Web API to use only bearer token authentication.
        config.SuppressDefaultHostAuthentication();
        config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));

        // Web API routes
        config.MapHttpAttributeRoutes();

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
    }
}

I also added preflight request in glabal.asax like below;

    protected void Application_BeginRequest()
    {
        if (Request.Headers.AllKeys.Contains("Origin") && Request.HttpMethod == "OPTIONS")
        {
            Response.Headers.Add("Access-Control-Allow-Origin", "*");
            Response.Headers.Add("Access-Control-Allow-Headers", "Access-Control-Allow-Origin, Origin, Content-Type, Authorization");
            Response.Headers.Add("Access-Control-Allow-Methods", "GET, POST, PATCH, PUT, DELETE, OPTIONS");
            Response.Headers.Add("Access-Control-Max-Age", "1728000");
            Response.End();
        }
    }

But when i check in chrome, i got the following error in console.

No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.

If i use IE the error looks like

Origin file: not found in Access-Control-Allow-Origin header.

I don't know what i did wrongly

You need to pass in your EnableCostAttribute instance to your EnableCors method:

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

Open the file App_Start/WebApiConfig.cs. Add the following code to the WebApiConfig.Register method.

using System.Web.Http;
namespace WebService
{
    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            // New code
            config.EnableCors();

            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );
        }
    }
}

Next, add the [EnableCors] attribute to the TestController class:

using System.Net.Http;
using System.Web.Http;
using System.Web.Http.Cors;

namespace WebService.Controllers
{
    [EnableCors(origins: "*", headers: "*", methods: "*")]
    public class TestController : ApiController
    {
        // Controller methods not shown...
    }
}

If you use OAuthAuthorizationServerProvider, you can try to do some like this:

public class SimpleAuthorizationServerProvider : OAuthAuthorizationServerProvider
    {
        public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
        {
            context.Validated();
            return Task.FromResult<object>(null);
        }

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



        }
    }