Подтвердить что ты не робот

401 ответ на запрос CORS в IIS с включенным Windows Auth

Я пытаюсь включить поддержку CORS в моем проекте WebAPI, и если я включу анонимную аутентификацию, тогда все будет хорошо, но с отключенной анонимной аутентификацией Windows Auth +, отправляемый запрос OPTIONS возвращает 401 несанкционированный ответ. Сайт, запрашивающий его, находится на домене DOMAIN, поэтому он должен иметь возможность выполнить вызов, есть ли способ обойти проблему без отключения проверки подлинности Windows?

4b9b3361

Ответ 1

От MS:

Если вы отключите анонимную аутентификацию, его дизайн, который IIS вернет 401 для любого запроса. Если они включили аутентификацию Windows, ответ 401 в этом случае будет иметь заголовок WWW-Authenticate, чтобы клиент мог начать аутентификацию. Затем возникает вопрос, может ли клиент, используемый клиентом, выполнить проверку подлинности Windows или нет.

Наконец, кажется, что может возникнуть основной вопрос о том, возможно ли его настроить или нет, чтобы разрешить анонимный доступ для одного глагола (в этом случае OPTIONS), но для проверки подлинности других глаголов требуется проверка подлинности Windows. IIS не поддерживает это через простую конфигурацию. Возможно, это можно будет получить, включив анонимную проверку подлинности Windows и Windows, установив списки ACL в содержимом, запрещающем доступ к анонимному пользователю, а затем настройте отображение обработчика для рассматриваемого URL-адреса, чтобы он не проверял существование файл, связанный с URL-адресом. Но для этого нужно немного поиграть.

Ответ 2

Вы можете разрешить только глагол OPTIONS для анонимных пользователей.

<system.web>
  <authentication mode="Windows" />
    <authorization>
      <allow verbs="OPTIONS" users="*"/>
      <deny users="?" />
  </authorization>
</system.web>

В соответствии со спецификациями W3C браузер не включает учетные данные пользователя из предпрограммы CORS: https://dvcs.w3.org/hg/cors/raw-file/tip/Overview.html#preflight-request

Ответ 3

Несколько лет спустя, но через ответ от @dariusriggins и @lex-li мне удалось добавить следующий код в мой Global.asax:

    public void Application_BeginRequest(object sender, EventArgs e)
    {
        string httpOrigin = Request.Params["HTTP_ORIGIN"];
        if (httpOrigin == null) httpOrigin = "*";
        HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", httpOrigin);
        HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
        HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, X-Token");
        HttpContext.Current.Response.AddHeader("Access-Control-Allow-Credentials", "true");

        if (Request.HttpMethod == "OPTIONS")
        {
            HttpContext.Current.Response.StatusCode = 200;
            var httpApplication = sender as HttpApplication;
            httpApplication.CompleteRequest();
        }
    }

httpOrigin фактически просматривается в списке разрешенных хостов, но это просто сложные вещи. Это означает, что все остальные запросы проверяются, но параметры просто возвращаются.

Спасибо за этот вопрос, я бы потерялся без него!

Ответ 4

Самый простой способ исправить это - создать правило перезаписи с условием request_method = ^ OPTIONS $. Затем установите действие как настраиваемый ответ, установите его на 200 OK. Затем все запросы параметров будут отвечать 200, а не 401. Это исправит проблему CORS.

Конечно, вам все равно нужно удостовериться, что у вас есть правильные заголовки запроса кросс-контентов.

Это остановит запросы параметров (у которых нет учетных данных), ответивших на 401, когда включен встроенный auth.

Ответ 5

Принятый ответ правильный, однако я некоторое время устранял проблему api для отдыха с помощью "node с модулем iisnode и npm cors", и было неудобно просто включать анонимную аутентификацию для всех пользователей. С его приложением node тег system.web мало что делает. Я получил следующее дополнение к web.config:

<system.webServer>
<security>
  <requestFiltering>
    <hiddenSegments>
      <add segment="node_modules" />
    </hiddenSegments>
  </requestFiltering>
  <authorization>
    <add accessType="Allow" verbs="OPTIONS" users="?" />
    <add accessType="Deny" verbs="GET, PUT, POST, DELETE" users="?" />
  </authorization>
</security>
</system.webServer>

Ответ 6

Сегодня я столкнулся с той же проблемой из-за ошибки в IE 10 и 11, я использую ServiceStack вместо WebApi, но подход может работать и на вас.

  • Включено Интегрированная и анонимная аутентификация Windows на веб-сайте IIS.
  • У вас есть серия фильтров на конвейере ServiceStack,
    • Для обработки запроса Cors и OPTIONS в разделе "Запрос параметров" я добавляю необходимые заголовки и завершаю запрос,
    • Фильтр для проверки, включая HttpRequest, аутентифицирован?,
    • и т.д. фильтр,

После прохождения всех фильтров он выполняет службу.

CorsFeature.cs

AuthenticateFilter

В моем AppHost

appHost.Plugins.Add(new CorsFeature());

appHost.RequestFilters.Add(AuthenticateFilter.Authenticate);

Я изменил CorsFeature для обработки OptionRequest в дополнение к добавлению заголовков, Authenticate Filter для проверки подлинности запросов!

Ответ 7

Связанный вопрос: IIS угоняет запрос CORS Preflight OPTIONS

Слияние информации из ответов, найденных в нескольких местах. Если вам нужно включить CORS для метода страницы ASP.net с проверкой подлинности Windows в интрасети, это то, что, кажется, работает. Без изменений в web.config это не сработает.

Вы должны добавить это в Global.asax

    protected void Application_BeginRequest(object sender, EventArgs e)
    {
        string httpOrigin = HttpContext.Current.Request.Params["HTTP_ORIGIN"] ?? HttpContext.Current.Request.Params["ORIGIN"] ?? "*";
        HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", httpOrigin);
        HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
        HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, X-Token");
        HttpContext.Current.Response.AddHeader("Access-Control-Allow-Credentials", "true");

        if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
        {
            HttpContext.Current.Response.StatusCode = 200;
            var httpApplication = sender as HttpApplication;
            httpApplication.CompleteRequest();
        }
    }

И это к web.config

 <system.webServer>
    <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>
  </system.webServer>

Ответ 8

Я использую Web API и OWIN, и я пробовал каждое предлагаемое решение, но единственное, что сработало, было следующее

//use it in your startup class
app.Use((context, next) =>
{
    if (context.Request.Headers.Any(k => k.Key.Contains("Origin")) && context.Request.Method == "OPTIONS")
    {
        context.Response.StatusCode = 200;
        context.Response.Headers.Add("Access-Control-Allow-Origin", new string[1] { "ALLOWED_ORIGIN" });
        context.Response.Headers.Add("Access-Control-Allow-Headers", new string[4] { "Origin", "X-Requested-With", "Content-Type", "Accept" });
        context.Response.Headers.Add("Access-Control-Allow-Methods", new string[5] { "GET", "POST", "PUT", "DELETE", "OPTIONS" });
        context.Response.Headers.Add("Access-Control-Allow-Credentials", new string[1] { "true" });

        return context.Response.WriteAsync("");
    }

    return next.Invoke();
});

//this is important! Without it, it didn't work (probably because the middleware was too late)
app.UseStageMarker(PipelineStage.Authenticate);

вам нужно вставить этот код где-нибудь в один из классов запуска OWIN. Очень важно называть app.UseStageMarker(PipelineStage.Authenticate), потому что в противном случае проверка предполета не удалась. Дополнительная информация для UseStageMarker → https://docs.microsoft.com/en-us/aspnet/aspnet/overview/owin-and-katana/owin-middleware-in-the-iis-integrated-pipeline

Также важно, чтобы вы явно определяли разрешенные заголовки. Он будет терпеть неудачу, если вы используете * в качестве заполнителя.

Может быть, это помогает кому-то.

Ответ 9

Я понимаю, что это старый вопрос с несколькими возможными решениями (а также с большим количеством вопросов), но на случай, если кто-нибудь еще столкнется с этим, IIS CORS 1.0 будет доступен с ноября 17 года:

https://blogs.iis.net/iisteam/introducing-iis-cors-1-0

https://docs.microsoft.com/en-us/iis/extensions/cors-module/cors-module-configuration-reference

Вы можете скачать его с помощью IIS Windows Platform Installer (WPI). Это должно решить многие из ваших проблем аутентификации CORS. Наслаждайтесь!

Ответ 10

Что работало для меня (при работе с AngularJS или JQuery), нужно добавить withCredentials: true для каждого запроса на клиенте:

$http.get("http://localhost:88/api/tests", {withCredentials :true})

И включение CORS на сервере, это было сделано с Microsoft.Owin.Cors от nuget и добавлением его в Startup, как показано ниже:

public void Configuration(IAppBuilder app)
    {
        HttpConfiguration config = new HttpConfiguration();

        ConfigureOAuth(app);

        WebApiConfig.Register(config);
        app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
        app.UseWebApi(config);

    }

Литература:

Ответ 11

Расширение ответа, предоставленного @dariusriggins. Проверьте это сообщение: Microsoft | Разработчик: Собираем все вместе - учебное пособие по CORS

Для конфигураций IIS:

Правило авторизации

Authorization rule

На этапе авторизации (или событии авторизации) нам необходимо убедиться, что мы разрешаем только анонимные запросы из предварительной проверки CORS и требуем, чтобы на все остальные входящие запросы были предоставлены учетные данные аутентификации. Мы можем достичь этого с помощью Правил авторизации. Правило авторизации по умолчанию, предоставляющее всем пользователям доступ к сайту, уже существует и предоставляется по умолчанию IIS. Мы начнем с изменения этого правила, чтобы разрешить только анонимным пользователям, если они отправляют запросы, использующие глагол OPTIONS http. Ниже приведена целевая конфигурация в IIS для этого правила авторизации:

Изменить правило авторизации

Edit Authorization rule

Ответ 12

Включение SupportCredentials в EnableCorsAttribute в WebApiConfig.cs помогло:

public static void Register(HttpConfiguration config)
{        
    //enable cors request just from localhost:15136 
    var cors = new EnableCorsAttribute("http://localhost:15136", "*", "*");
    cors.SupportsCredentials = true;
    config.EnableCors(cors);

    //other stuff
}

https://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api

Убедитесь, что вы отправляете учетные данные при вызове из javascript ({withCredentials :true})