【问题标题】:preflight request in enabled CORS ASP.NET Web API 2 application with windows authentication使用 Windows 身份验证启用 CORS ASP.NET Web API 2 应用程序中的预检请求
【发布时间】: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 来调试请求时,一切都变得很好。

请告诉我如何修复它。

【问题讨论】:

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


    【解决方案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 中的问题。谢谢
    猜你喜欢
    • 2023-03-23
    • 2023-04-03
    • 2017-10-27
    • 2016-10-12
    • 2023-03-18
    • 1970-01-01
    • 2021-03-14
    • 2012-11-01
    相关资源
    最近更新 更多