CORS + Windows 身份验证无法与 Edge 或 IE 配合使用
Posted
技术标签:
【中文标题】CORS + Windows 身份验证无法与 Edge 或 IE 配合使用【英文标题】:CORS + Windows Authentication not playing nice with Edge or IE 【发布时间】:2018-07-05 04:49:36 【问题描述】:我遇到了仅在 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();
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
);
这是客户端项目中的脚本函数:
GetStatus = () =>
$.ajax(
type: "GET",
url: apiUrl,
dataType: "json",
crossDomain: true,
xhrFields:
withCredentials: true
,
contentType: "application/json; charset=UTF-8",
success: (result) =>
this.Status(result);
);
更新
按照建议,我修改了 Global.asax.cs 以确保每个请求都包含 Access-Control-Allow-Origin 和 Access-Control-Allow-Credentials。但是,这仍然会导致仅在 Edge 和 IE 中出现 401。它在 Chrome 中运行良好。
更新 2
我猜有些事情确实发生了变化。我错过了错误现在减少到以下内容:
这显然是因为我得到了适当的标题。然而,出于某种原因,尽管存在withCredentials: true
,Edge 和 IE 仍然不允许身份验证通过。我还缺少另一件吗?
【问题讨论】:
你用owin吗? @anılyıldırım 是的 @kettch 你解决了吗?我开始相信这是不可能的参考:social.technet.microsoft.com/Forums/windowsserver/en-US/… @IsaackRasmussen 抱歉,我被另一个优先事项分心了。我今天会回到这个问题,并仔细检查发布的答案。 【参考方案1】:ASP.NET (OWIN)
Install-Package Microsoft.Owin.Cors
Startup.cs:
app.UseCors(CorsOptions.AllowAll)
网页配置:
<system.webServer>
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<remove name="OPTIONSVerbHandler" />
<remove name="TRACEVerbHandler" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
</system.webServer>
【讨论】:
【参考方案2】:您需要在 GET 请求以及预检 OPTIONS 请求中返回 Access-Control-Allow-Origin
(ACAO) 和 Access-Control-Allow-Credentials
(ACAC) 标头。对于您传递 cookie/身份验证的每个跨域请求,都需要返回这两个标头。
最好/最简单/最干净的方法是编写代码,以便为包含 Origin 请求标头的所有请求(OPTIONS、GET、POST 等)添加 ACAO 和 ACAC 标头。然后,对于 OPTIONS 请求,也添加其他 Access-Control-Allow-* 标头...
另外,FWIW,在 ACAO 标头中返回 Origin 请求标头的值是一个明智的想法,而不是将其硬编码为 http://localhost:50281
。这样,如果您更改端口或其他任何内容,它仍然可以运行。
【讨论】:
我确保标题存在,但似乎并没有改变结果。以上是关于CORS + Windows 身份验证无法与 Edge 或 IE 配合使用的主要内容,如果未能解决你的问题,请参考以下文章
CORS 预检请求返回带有 Windows 身份验证的 HTTP 401
AngularJS + Asp.net WebApi - 由于 CORS,无法进行身份验证