使用 Windows 身份验证启用 CORS ASP.NET Web API 2 应用程序中的预检请求

Posted

技术标签:

【中文标题】使用 Windows 身份验证启用 CORS ASP.NET Web API 2 应用程序中的预检请求【英文标题】:preflight request in enabled CORS ASP.NET Web API 2 application with windows authentication 【发布时间】:2017-04-21 16:17:38 【问题描述】:

我有一个在我们的 Intranet 中使用的 Web API 应用程序。我们还使用 Windows 身份验证来限制谁可以访问 Intranet 中的这些 Web API。

此外,我们还有一个 angularJS 应用程序。它使用 WEB API 应用程序。这些应用程序的领域是不同的。因此我们使用了 CORS。

为了启用 CORS,我们使用了 Microsoft CORS Nuget 包。

public static class WebApiConfig

    public static void Register(HttpConfiguration config)
    

        config.MapHttpAttributeRoutes();

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

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

我有两个 WEB API(GET 和 POST)。加载我的 UI 时,会调用 GET API。当用户单击保存按钮时,会调用 POST API。

[RoutePrefix("api/call")]
[Authorize]
public class CallController : TecApiController

    [HttpGet]
    [Route("GetInfo")]
    public IHttpActionResult GetCallInfo(int Id)
    
       //return Model
    

    [HttpPost]
    [Route("saveInfo")]
    public IHttpActionResult SetUncompleteCallToDismissed([FromBody] Model model)
    
        // Save Model
    

我调用 API 的 AngularJS 服务如下

$http.get(apiEndPoint + 'GetInfo/' + Id,  withCredentials: true )
            .then(function (response)  return response.data; ,    handleError);

$http.post(apiEndPoint + 'saveInfo/', model,  withCredentials: true )
            .then(function (response)  return response.data; , handleError);

我的问题是 GET 方法运行良好。但是当我点击帖子时,我的浏览器控制台出现以下错误:

XMLHttpRequest 无法加载 http://localhost:35059/api/call/saveInfo。回应 预检请求未通过访问控制检查:否 请求中存在“Access-Control-Allow-Origin”标头 资源。因此不允许使用原点“http://localhost:3000” 使用权。响应的 HTTP 状态代码为 401。

这里发生的最复杂的事情是当我运行 Fiddler 来调试请求时,一切都变得很好。

请告诉我如何修复它。

【问题讨论】:

【参考方案1】:

好的,对于有同样问题的人。

当您启用 Windows 身份验证时,您不能使用 * 作为来源。 您必须指定来源。

在我的例子中,在 WebApiConfig.cs

中定义以下部分
 var cors = new EnableCorsAttribute("http://IP:PORT", "*", "*")  SupportsCredentials = true ;
            config.EnableCors(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://IP:PORT");
                Response.Headers.Add("Access-Control-Allow-Headers", "Origin, Content-Type, X-Auth-Token");
                Response.Headers.Add("Access-Control-Allow-Methods", "GET, POST, PATCH, PUT, DELETE, OPTIONS");
                Response.Headers.Add("Access-Control-Allow-Credentials", "true");
                Response.Headers.Add("Access-Control-Max-Age", "1728000");
                Response.End();
            
        

Response.Headers.Add("Access-Control-Allow-Credentials", "true"); 如果您的 web api 中有 windows 身份验证,则此部分是强制性的。

最后一件事(也是最烦人的事情)是你不能在你的 ApiController 中使用RouteRoutePrefix 属性。 您必须在WebApiConfig.cs 中定义所有路由,因为路由属性会更改请求的标头并删除所有 Windows 身份验证和 CORS 所需的标头。

config.Routes.MapHttpRoute(
                    name: "GetInfo",
                    routeTemplate: "api/call/getinfo",
                    defaults: new  action = "GetCallInfo", controller = "Call" 
                );

【讨论】:

这对我来说是 webapi 和 angular9 中的问题。谢谢

以上是关于使用 Windows 身份验证启用 CORS ASP.NET Web API 2 应用程序中的预检请求的主要内容,如果未能解决你的问题,请参考以下文章

Angular 7 .net 核心 2.2 WebApi Windows 身份验证 CORS

带有 Windows 身份验证的 Web api 中的 Cors 问题

启用 CORS 的 Web Api 2 facebook 身份验证

Angular/Node/Express/Passport 跨域问题 - 启用 CORS Passport Facebook 身份验证

带有 Windows 身份验证的 CORS

CORS + Windows 身份验证无法与 Edge 或 IE 配合使用