Angular 4 HTTP POST с проблемой предварительной проверки подлинности Windows

Я использую angular 4 с веб-API ASP.NET 2 на бэкэнде с включенной проверкой подлинности Windows. У меня есть один пост и один получить API. ПОЛУЧИТЬ работает нормально. Но для POST я получаю эту ошибку

Ответ на предварительную проверку имеет неверный код состояния HTTP 401.

Это означает, что я получаю несанкционированную ошибку для метода OPTIONS, которая, как я знаю, не должна иметь место, потому что метод OPTIONS никогда не вызывается с учетными данными пользователя.

в angular я вызываю API следующим образом

      let requestOptions = new RequestOptions({
      withCredentials: true,
      headers: new Headers({
        'content-type': 'application/json'
      })
    })
    this.http.post("someapiendpoint", JSON.stringify(data), requestOptions).subscribe(data => {
      debugger;
    });

Я установил весь заголовок CORS в своей веб-конфигурации следующим образом

        <add name="Access-Control-Expose-Headers " value="WWW-Authenticate"/>
        <add name="Access-Control-Allow-Origin" value="http://localhost:4200" />
        <add name="Access-Control-Allow-Headers" value="accept, authorization, Content-Type" />
        <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
        <add name="Access-Control-Allow-Credentials" value="true" />

Также у меня есть следующий в моем блоке аутентификации web.config

             <authentication>

                <anonymousAuthentication enabled="false" userName="" />

                <basicAuthentication enabled="false" />

                <clientCertificateMappingAuthentication enabled="false" />

                <digestAuthentication enabled="false" />

                <iisClientCertificateMappingAuthentication enabled="false">
                </iisClientCertificateMappingAuthentication>

                <windowsAuthentication enabled="true">
                    <providers>
                        <add value="Negotiate" />
                        <add value="NTLM" />
                    </providers>
                </windowsAuthentication>

            </authentication>

я пытался удалить

headers: new Headers({
            'content-type': 'application/json'
          })

Ниже приведен код моего контроллера для веб-API.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using System.DirectoryServices;
using System.DirectoryServices.AccountManagement;

namespace Backend.Controllers
{
    public class DemoController : ApiController
    {
        Entities db = new Entities();
        public DemoController ()
        {
        }

        [HttpPost]
        [ActionName("postevent")]
        public IHttpActionResult PostEvent(Demo data)
        {
            db.Demos.Add(data);
            db.SaveChanges();
            return Ok();
        }

    }
}

из моего углового кода, но это не помогло. Я также пытался заменить его на «text/html», но это тоже не сработало. Может ли кто-нибудь сказать мне, что я делаю неправильно. Как я предполагаю, он должен работать нормально, если он работает для GET.


person nikhil mehta    schedule 03.08.2017    source источник
comment
Какую систему веб-API вы используете?   -  person Bailey Miller    schedule 04.08.2017
comment
Для C# Web Api 2.0 вам необходимо объявить метод публикации как таковой с атрибутом [HttpPost].   -  person Bailey Miller    schedule 04.08.2017
comment
@BaileyMiller да, я сделал это и добавил имя действия и маршрут   -  person nikhil mehta    schedule 04.08.2017
comment
Могу ли я увидеть больше фактического кода контроллера?   -  person Bailey Miller    schedule 04.08.2017
comment
Вы уверены, что операция GET аутентифицируется? Есть ли в вашем методе контроллера атрибут [Authorize]?   -  person Sal    schedule 04.08.2017
comment
@BaileyMiller Добавил код в вопрос   -  person nikhil mehta    schedule 04.08.2017
comment
@Paul, нет, у моего контроллера нет [Авторизация]. Я предполагаю, что предварительная проверка запускается, поскольку заголовок типа контента не прост, поскольку в качестве значения он имеет application/json.   -  person nikhil mehta    schedule 04.08.2017
comment
@nikhilmehta это тот же контроллер, у которого также есть конечная точка получения?   -  person Bailey Miller    schedule 04.08.2017
comment
@nikhilmehta Также зачем включать CORS через web.config, если вы используете Web Api 2.0, попробуйте использовать Owin для настройки cors   -  person Bailey Miller    schedule 04.08.2017


Ответы (2)


Во всех темах, которые я читал, говорится, что вы не можете полностью отключить анонимную аутентификацию, иначе предварительный запрос OPTIONS не будет работать. Это потому что:

Согласно спецификациям W3C, браузер исключает учетные данные пользователя из предварительной проверки CORS:

См., например, этот раздел: WebAPI CORS с проверкой подлинности Windows — разрешить Анонимный запрос OPTIONS

В основном решение состоит в том, чтобы позволить вызовам OPTIONS проходить без аутентификации. А для этого необходимо включить анонимную аутентификацию.

В этом вопросе: 401 ответ на запрос CORS в IIS с включенной проверкой подлинности Windows В ответе предлагается следующий файл web.config

<system.web>
  <authentication mode="Windows" />
    <authorization>
      <allow verbs="OPTIONS" users="*"/>
      <deny users="?" />
  </authorization>
</system.web>
person Sal    schedule 04.08.2017
comment
Нет это не помогло - person nikhil mehta; 04.08.2017
comment
Я обнаружил, что это исправление работает нормально. Используя IIS, мне пришлось включить как анонимную, так и оконную аутентификацию. Затем добавьте указанные выше параметры аутентификации/авторизации в файл web.config. После этого любые запросы OPTIONS, отправленные angular на мой веб-сайт API, были успешно пройдены. - person Stuart; 13.06.2018

Ответ Павла правильный. У меня точно такие же настройки и все работает.

Вам необходимо включить как анонимную, так и Windows-аутентификацию, добавить фрагмент из ответа Пола в web.config, чтобы разрешить неаутентифицированные запросы OPTIONS, и добавить атрибут [Authorize] на свой контроллер.

person Andrei Matracaru    schedule 06.08.2017