Asp. Net MVC Запрос WebApi CORS не выполняется - не предложено никаких решений, влияющих на результат - PullRequest
0 голосов
/ 19 февраля 2020

У меня есть веб-приложение Asp. Net NVC5 (работает под Visual Studio 2017) на локальном хосте: 59569 (SiteApi). У меня есть второй веб-сайт (также работает под Visual Studio 2017) на localhost: 61527 (SiteClient), где однажды загруженная страница выполняет следующий API-вызов SiteApi:

$http({
    url: 'http://localhost:59569/api/V2/' + alias,
    method: 'POST',
    data: pm,
    xhrFields: { withCredentials: true },
    headers: { 'Content-Type': 'application/json; charset=utf-8' }
    })
    .then(th, ex);

ПРИМЕЧАНИЕ. Я пробовал это с и без информации xhrFields + withCredentials с использованием Microsoft IE, Microsoft Edge и Chrome.

Назад на SiteApi результирующий предполётный вызов для OPTIONS перехватывается следующим кодом в Global.asax, который выполняется точно так, как написано и Я могу проследить через оператор if, когда его вызывает входящий вызов для OPTIONS.

protected void Application_BeginRequest()
{
    if (Request.Headers.AllKeys.Contains("Origin") && Request.HttpMethod == "OPTIONS")
    {
        Response.Clear();
        Response.Headers.Add("Access-Control-Allow-Origin", "*");
        Response.Headers.Add("Access-Control-Allow-Headers", "Content-Type, Accept, X-Requested-With, Session");
        Response.Flush();
        Response.End();
    }
}

Намерение состоит в том, чтобы отправить желаемые заголовки обратно клиенту, чтобы позволить CORS функционировать должным образом - однако сразу после того, как этот код снова выполнив веб-страницу в SiteClient, сообщает, что запрос был заблокирован из-за отсутствия отсутствующего заголовка «Access-Control-Allow-Origin», и я вижу, что ни один из указанных мной заголовков не вернул его клиенту.

В попытке заставить CORS работать У меня установлены следующие пакеты nuget в проекте SiteAPI.

  • Microsoft.As pNet .Cors
  • Microsoft.As pNet .WebApi.Cors

Я изменил метод WebApiConfig.Register (), чтобы он включал:

   // Web API configuration and services
   config.EnableCors();

Я пробовал много вариантов добавления атрибутов фильтра в мой контроллер, например:

[EnableCors("*", "*", "*", SupportsCredentials = true)]

Я попытался добавить свой собственный собственный ActionFilterAttribute из решений, найденных в других связанных с CORS вопросах о stackoverflow, например (среди прочих):

    public override void OnActionExecuting(System.Web.Mvc.ActionExecutingContext filterContext)
    {
        filterContext.RequestContext.HttpContext.Response.AddHeader("Access-Control-Allow-Origin", "*");
        base.OnActionExecuting(filterContext);

У меня есть следующее в моем файле web.config:

<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>

У меня есть ВСЕ эти решения, живущие в моем проекте, и, несмотря на это, я все еще получаю ошибки CORS на стороне клиента.

Итак, предостережение в том, что я тоже иметь собственный фильтр, который проверяет безопасность при каждом вызове API - который прекрасно работает со ВСЕМИ вызовами, сделанными со страниц, работающих на SiteApi. В случае вызовов из SiteClient (вызовы CORS) фильтр безопасности вообще не срабатывает, хотя я получаю 401 сообщение об ошибках на клиенте в дополнение к ошибкам из-за отсутствующих заголовков, связанных с CORS.

Я очистил кеши всех браузеров и самого сервера. Я впервые работаю с CORS, и я уже устал работать с тем, что действительно должно быть простым решением. Ищите решения здесь и были бы признательны за помощь от тех, кто в курсе.

Заголовки запросов:

Accept: application/json, text/plain, */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Connection: keep-alive
Content-Length: 2
Content-Type: application/json; charset=UTF-8
Host: localhost:59569
Origin: http://localhost:61527
Referer: http://localhost:61527/Home/Index
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-site
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.106 Safari/537.36 Edg/80.0.361.54

Заголовки ответов:

Cache-Control: private
Content-Length: 6115
Content-Type: text/html; charset=utf-8
Date: Wed, 19 Feb 2020 00:46:06 GMT
Server: Microsoft-IIS/10.0
WWW-Authenticate: Negotiate
WWW-Authenticate: NTLM
X-Powered-By: ASP.NET
X-SourceFiles: =?UTF-8?B?QzpcVXNlcnNcbngyMDA4MjZcRGV2XFRlY2hJVFxFQVNJV2ViQXBwXGFwaVxWMlxHZXRDb21tYW5kcw==?=

1 Ответ

1 голос
/ 19 февраля 2020

Это поток, который я использую. Иногда браузеры не любят "*". В других случаях браузеры тоже не любят localhost. Это логика c, которую я использую (измените разрешающие заголовки, как считаете нужным). Это может быть тот факт, что вы также не разрешаете заголовки контроля доступа в своих разрешенных заголовках:

[Добавить это в Global.asax]

protected void Application_BeginRequest(object sender, EventArgs e)
{
        var originKey =
            Request.Headers.AllKeys.FirstOrDefault(
                a => a.Equals("origin", StringComparison.InvariantCultureIgnoreCase));

        if (originKey != null && Request.HttpMethod == "OPTIONS"))
        {
// Optional Whitelist check here can return without the headers below to reject CORS
            Response.Headers.Add("Access-Control-Allow-Origin", Request.Headers[originKey]);
            Response.Headers.Add("Access-Control-Allow-Credentials", "true");
            Response.Headers.Add("Access-Control-Allow-Methods", "GET, POST, PUSH, DELETE, OPTIONS");
            Response.Headers.Add("Access-Control-Allow-Headers",
                "Authorization, Content-Type, Access-Control-Allow-Headers, X-Requested-With, Access-Control-Allow-Method, Accept");

            Response.Flush();
            Response.End();
            return;
        }
}
...