Метод OPTIONS не запрашивает учетные данные, 401 [дубликат]

Оператор == проверяет, имеют ли две переменные одинаковые ссылки (aka указатель на адрес памяти).

String foo = new String("abc");
String bar = new String("abc");

if(foo==bar)
// False (The objects are not the same)

bar = foo;

if(foo==bar)
// True (Now the objects are the same)

В то время как метод equals () проверяет, ссылаются ли две переменные на объекты, имеющие одно и то же состояние (значения).

String foo = new String("abc");
String bar = new String("abc");

if(foo.equals(bar))
// True (The objects are identical but not same)

Приветствия: -)

32
задан dariusriggins 23 May 2012 в 16:25
поделиться

10 ответов

От MS:

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

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

13
ответ дан dariusriggins 17 August 2018 в 15:49
поделиться
  • 1
    Просто заметили, что многие парни испытали ошибки 401, когда их веб-API защищен аутентификацией Windows или таковой. Запросы предварительной проверки CORS не содержат учетных данных, поэтому IIS ответит 401.2 еще до того, как ASP.NET коснется их. Грязное обходное решение заключается в том, чтобы написать HTTP-модуль и подключиться к конвейеру IIS, который регистрируется в событии HttpApplication.BeginRequest, где этот модуль возвращает ожидаемый ответ 200 для запросов перед полетом. Это обходное решение применимо только к интегрированному режиму IIS 7+. К сожалению, поддержка Microsoft может не знать об этом совете. – Lex Li 11 January 2015 в 13:17
  • 2
    Просто сделал сообщение в блоге, blog.lextudio.com/2014/11/… с дополнительной информацией о пользователях IIS 6 и классическом режиме. – Lex Li 11 January 2015 в 13:44
  • 3
    @LexLi читает ваш блог, но, к сожалению, вы не детализировали точную реализацию события BeginRequest, поэтому я не понимаю, что все включить в ответ 200 (например, заголовки и т. Д.). Я понимаю, как создавать HttpModules, просто хотел бы уточнить, что ответить на запрос предполетной проверки. – Thiago Silva 27 January 2015 в 21:31
  • 4
    @ThiagoSilva, я только что обновил сообщение, чтобы указать, какую статью вы должны прочитать. developer.mozilla.org/en-US/docs/Web/HTTP/… содержит даже образцы запросов / ответов, чтобы вы могли легко следовать. – Lex Li 28 January 2015 в 11:24
  • 5
    @ lex-li: Я только что опубликовал ответ, который использует только global.asax, с которым я бы не приблизился без вашей статьи в блоге. Благодаря! – Stu 2 September 2015 в 10:57

Я использую 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

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

Возможно, это помогает кому-то.

1
ответ дан Arikael 17 August 2018 в 15:49
поделиться

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

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

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

CorsFeature.cs

AuthenticateFilter

В моей AppHost,

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

appHost.RequestFilters.Add(AuthenticateFilter.Authenticate);

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

3
ответ дан Cyril Gandon 17 August 2018 в 15:49
поделиться
  • 1
    Привет, вы можете немного подробнее узнать, что вы сделали? Я сталкиваюсь с аналогичными проблемами, и я также использую ServiceStack, который развертывается через SharePoint 2013 – link64 16 September 2014 в 06:32
  • 2
    Я пропускаю проверку. Является ли пользователь аутентифицирован для запросов OPTIONS. Я добавлю образец кода. – Sathish Naga 16 September 2014 в 19:10

Вы можете разрешить только глагол 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

35
ответ дан Jan Remunda 17 August 2018 в 15:49
поделиться
  • 1
    Требуется ли для IIS анонимный модуль auth? – UserControl 6 January 2015 в 17:07
  • 2
    Видимо, да. Анонимная аутентификация дает пользователям доступ к общедоступным областям вашего веб-сайта или FTP-сайта без запроса имени пользователя или пароля. & quot; bit.ly/1wjLdO9 – Jan Remunda 6 January 2015 в 17:41
  • 3
    Это должен быть принятый ответ. – slashp 20 October 2015 в 18:14
  • 4
    Это не работает! – AhmadWabbi 6 July 2016 в 08:11
  • 5
    Это абсолютно работает, но есть и есть: порядок значителен. Вы должны указать «разрешить». , и "deny" тег второй. Сделайте это по-другому, и вы будете разочарованы. – Stuart 10 August 2017 в 21:44

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

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

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

4
ответ дан Luke Basil 17 August 2018 в 15:49
поделиться
  • 1
    Вы видите какие-либо потенциальные проблемы с безопасностью? – Paul Lernmark 3 March 2016 в 15:04

Включение 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})

0
ответ дан Miroslav Adamec 17 August 2018 в 15:49
поделиться
  • 1
    Я пытаюсь сделать то же самое, но без учетных данных. Не повезло даже с анонимным auth on – jpfreire 12 January 2017 в 15:19

Принятый ответ правильный, однако я некоторое время устранял проблему rest api с установкой «узел с модулем iisnode и npm cors», и было неудобно просто включать анонимную аутентификацию для всех пользователей. Поскольку его узловое приложение тегом 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>
2
ответ дан mrplatina 17 August 2018 в 15:49
поделиться
  • 1
    «Работал для меня». в IIS + Basic Auth, который имеет такую ​​же проблему:} – user2864740 6 August 2018 в 21:01

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

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

И включение CORS на сервере, это было сделано с Microsoft.Owin .Cors from 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);

    }

Ссылки:

0
ответ дан Philip Patrick 17 August 2018 в 15:49
поделиться

Несколько лет спустя, но через ответ от @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 действительно просматривается в список разрешенных хостов, но это просто сложные вещи. Это означает, что все остальные запросы проверяются, но параметры просто возвращаются.

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

17
ответ дан Stu 17 August 2018 в 15:49
поделиться
  • 1
    Я пробовал много разных способов включить CORS с WebAPI, работающий в IIS для клиента Angular 2, включая добавление его в web.config, аннотации данных о действиях моего контроллера и вызов «EnableCors» в WebApiConfig.Register. Это решение является только одним , который фактически работал с Windows Authentication (NTLM), наряду с тем, что HTTP-адрес Angular 2 отправил withCredentials в HTTP-заголовок. Спасибо! – Ben Cottrell 5 December 2016 в 14:51
  • 2
    Это великолепно! Работает как шарм! Вам даже не нужно указывать его в Application_BeginRequest. Вы можете даже поместить его в загрузку страницы, если это всего лишь одна страница, которую вы хотите разрешить. – Shiroy 7 April 2017 в 05:19
0
ответ дан Inphinite Phractals 6 September 2018 в 10:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: