【问题标题】:Cross Domain Request w/ Cors带 Cors 的跨域请求
【发布时间】:2016-05-05 03:53:02
【问题描述】:

我有一个 ember 解决方案,它在 http://localhost:4200 上本地运行。它从我的使用 Windows 身份验证的 WebApi 应用程序请求数据。目前在http://localhost:11470 上运行。由于某些奇怪的原因,当我的 WebApi 应用程序响应时,它会遗漏以下内容,例如:Access-Control-Allow-Origin。从而抛出以下异常:

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

如果我查看请求,我清楚地看到 WebApi 应用程序未在标头中包含此类数据。我该如何纠正我的问题?

// Inside: 'WebApiConfig'
configuration.EnableCors(new EnableCorsAttribute("http://localhost:4200", "*", "*") { SupportsCredentials = true });

// Controller:
[Route("api/Authentication/Logins")]
public IHttpActionResult Login()
{
     if (User.Identity.IsAuthenticated)
          return Ok();      

     return Unauthorized();
}

// Ember Ajax:
Ember.$.ajax({
     type: "GET",
     url: 'http://localhost:11470/api/Authentication/logins',
     crossDomain: true,
     headers:{
          'Authorization': 'WWW-authenticate'
     },
     xhrFields: {
          withCredentials: true
     },
     error: function() { console.log('Error'); },
     success: function() { console.log('Working?'); }
});

我什至尝试了以下方法:

  • 强制web.config中的标头信息。
  • IHttpActionResult的自定义实现
  • ActionFilterAttribute 的自定义过滤器实现。

那些在控制台错误之前没有命中。为 WebApi 应用程序启用的所有功能都是 Windows 身份验证,如果我直接导​​航到 localhost:11470/api/authentication/login,它会提示我输入我的 Active Directory 凭据,然后正确响应。

我已经阅读了几篇文档,例如:

我无法找到可靠工作的解决方案,我缺少什么或不理解什么?我知道它需要标头,但是为什么 WebApi 的 Cors 库没有发送它?

【问题讨论】:

  • 为什么不在开发中使用 ember-cli 中的 --proxy,因为在生产中您希望将 ember 应用程序托管在与 asp.NET 应用程序相同的 IIS 中?
  • 这仍然会导致同样的错误,是的,你是对的,我可以在同一个 IIS 应用程序池和实例中同时运行。但我想了解我遇到这种情况的原因。
  • 您能否在进行 AJAX 调用时提供有关请求/响应标头的更多信息,可能正在使用 fiddler 之类的工具
  • 基本上你的请求头应该有 Origin: localhost:4200 并且响应头应该有 Access-Control-Allow-Origin: localhost:4200 或 *
  • @CleanCrispCode 是的,我可以,我知道我需要 Access-Control-Allow-Origin,但由于某些奇怪的原因,我的 WebApi 没有将其发回。

标签: c# ember.js asp.net-web-api cors cross-domain


【解决方案1】:

添加包

<?xml version="1.0" encoding="utf-8"?>
 <packages>
   <package id="Microsoft.AspNet.Cors" version="5.2.3" targetFramework="net461" />
   <package id="Microsoft.AspNet.WebApi.Client" version="5.2.3" targetFramework="net461" />
   <package id="Microsoft.AspNet.WebApi.Core" version="5.2.3" targetFramework="net461" />
   <package id="Microsoft.AspNet.WebApi.Cors" version="5.2.3" targetFramework="net461" />
   <package id="Newtonsoft.Json" version="6.0.4" targetFramework="net461" />
 </packages>


public static void Register(HttpConfiguration config)
         {
             config.MapHttpAttributeRoutes();

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

             config.EnableCors(cors);
             config.Routes.MapHttpRoute(
                 name: "DefaultApi",
                 routeTemplate: "api/{controller}/{id}",
}

jQuery

url: ApiPath + "/api/Orders/OrderNumber/" + orderNo,
         dataType: "json",
         crossDomain: true,
         headers: { "__RequestVerificationToken": AntiForgery.getToken() },
         //headers: { "__RequestVerificationToken": AntiForgery.getToken() },
         success: function (data) {
             $.each(data.ItemList, function (key, value) {
                 SettingArrayLists(value);
}}}}

【讨论】:

    【解决方案2】:

    我在使用 Microsoft.AspNet.WebApi.Cors 包时遇到了完全相同的问题。

    尝试检查 Web API 的一些事情(您提到的一些您尝试过,但我将它们与我尝试过的详细信息一起列出,以防细节存在差异):

    1. 如果您的 API 我们使用登录信息,您需要允许 CORS 通过 SupportsCendentials 属性发送“身份验证”标头,应该通过以下方式启用:

      config.EnableCors(new EnableCorsAttribute("http://localhost:4200", "", "") { SupportsCredentials = true });

    但是这个解决方案实际上并没有为我工作,它没有在我的 /token OPTIONS 飞行前设置 CORS 标头,但它可能与库或 WebAPI 版本存在版本差异。

    1. 在您的 Web.config 中检查您是否正在禁用 OPTIONS 处理程序(我认为这是默认行为),这是飞行前尝试调用的:

    在 system.webServer.handlers 下:

    <!--<remove name="OPTIONSVerbHandler" />--> <!--Allow options handling (preflight requests) by removing this line-->
    
    1. 强制它:在 system.webServer.httpProtocol 下为您的自定义标头添加所有这些以强制它们通过(如果您尝试这样做,请禁用其他 CORS 选项)。
    <customHeaders>
        <!--Enable CORS for all requests (TODO Fix this, move to OWIN settings) -->
        <add name="Access-Control-Allow-Origin" value="*" />
        <add name="Access-Control-Allow-Headers" value="Origin, Content-Type, Authorization" />
        <add name="Access-Control-Allow-Methods" value="GET, POST, OPTIONS, PUT, DELETE" />
      </customHeaders>
    

    这些更改允许我的 API 以正确的标头响应,我建议从那里开始。

    1. 而不是使用 Microsoft.AspNet.WebApi.Cors CORS 包并将其设置在 WebApiConfig.cs 中,您可以直接在 Startup.cs 或 Startup.Auth.cs 中的 OWIN 中间位置上设置它,并且作为 FIRST 行中的任何一个,在任何其他 OWIN pineline 之前,添加:

      app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);

    【讨论】:

      猜你喜欢
      • 2020-12-08
      • 2018-09-10
      • 2014-12-21
      • 2020-08-16
      相关资源
      最近更新 更多