CORS + Windows身份验证与Edge或IE不兼容

Dev*_*ble 7 asp.net-mvc cors asp.net-web-api microsoft-edge

我有一个只在Edge和IE11中发生的CORS问题.Chrome工作正常.

我的设置是一个ASP.NET MVC5应用程序(客户端),它有一个脚本调用一个单独的ASP.NET MVC5应用程序(API),它只包含WebAPI控制器.两个应用程序中的安全性均通过Windows身份验

目前,在开发过程中,一切都在localhost上运行.

当客户端脚本调用API时,OPTIONS预检工作正常.但是,当GET发生这种情况时,Edge和IE会出现以下错误:

在此输入图像描述

在此图像中,localhost:50281是客户端,localhost:47205是API.

奇怪的是,呼叫实际上并没有击中控制器.控制器装饰有自定义AuthorizeAttribute,并且在那里的断点不会被击中.

以下是在API项目中如何设置CORS:

的Global.asax.cs

protected void Application_BeginRequest()
{
    if (Request.Headers.AllKeys.Contains("Origin") && Request.HttpMethod == "OPTIONS")
    {
        Response.Headers.Add("Access-Control-Allow-Origin", "http://localhost:50281");
        // Yes, there are too many headers. I've been working on this a while, and there are a few overkill options that have crept in
        Response.Headers.Add("Access-Control-Allow-Headers", "X-AspNet-Version,X-Powered-By,Date,Server,Accept,Accept-Encoding,Accept-Language,Cache-Control,Connection,Content-Length,Content-Type,Host,Origin,Pragma,Referer,User-Agent");
        Response.Headers.Add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, HEAD, OPTIONS");
        Response.Headers.Add("Access-Control-Allow-Credentials", "true");
        Response.Headers.Add("Access-Control-Max-Age", "600");
        Response.End();
    }
}
Run Code Online (Sandbox Code Playgroud)

WebApiConfig.cs

public static void Register(HttpConfiguration config)
{
    // Web API configuration and services
    var cors = new EnableCorsAttribute("http://localhost:50281", "*", "*");
    cors.SupportsCredentials = true;
    cors.PreflightMaxAge = 600;
    config.EnableCors(cors);
    // Web API routes
    config.MapHttpAttributeRoutes();

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

这是客户端项目中的脚本函数:

GetStatus = () => {
    $.ajax({
        type: "GET",
        url: apiUrl,
        dataType: "json",
        crossDomain: true,
        xhrFields: {
            withCredentials: true
        },
        contentType: "application/json; charset=UTF-8",
        success: (result) => {
            this.Status(result);
        }
    });
}
Run Code Online (Sandbox Code Playgroud)

更新

我修改了Global.asax.cs以确保每个请求都包含Access-Control-Allow-Origin和Access-Control-Allow-Credentials,如建议的那样.但是,这仍然只在Edge和IE中产生401.它在Chrome中运行良好.

更新2

我猜想有些事情发生了变化 我错过了错误现在减少到以下内容: 在此输入图像描述

这显然是我得到适当的标题.但是,由于某些原因,Edge和IE仍然没有让身份验证通过,尽管存在withCredentials: true.我还缺少另一件吗?

ror*_*itt 0

您需要通过 GET 请求以及预检 OPTIONS 请求返回Access-Control-Allow-Origin(ACAO) 和(ACAC) 标头。Access-Control-Allow-Credentials对于传递 cookie/身份验证的每个跨域请求,都需要返回这两个标头。

最好/最简单/最干净的方法是编码,以便对于包含 Origin 请求标头的所有请求(OPTIONS、GET、POST 等)添加 ACAO 和 ACAC 标头。然后,对于 OPTIONS 请求,添加其他 Access-Control-Allow-* 标头...

另外,FWIW,在 ACAO 标头中返回 Origin 请求标头的值是一个明智的想法,而不是将其硬编码为http://localhost:50281. 这样,如果您更改端口或其他任何内容,它仍然可以正常工作。