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

时间:2016-12-06 21:32:48

标签: c# angularjs asp.net-web-api cors

我有一个在我们的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 个答案:

答案 0 :(得分:2)

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

启用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");如果你的网络API中有Windows身份验证,那么这部分就是mandetory。

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

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