Есть ли ЛЮБОЙ способ подавить запрос на вход в браузер на ответ 401 при использовании XmlHttpRequest - PullRequest
8 голосов
/ 12 декабря 2008

Я использую функцию jQuert .ajax для вызова метода страницы. Сайт использует FormsAuthentication. Поэтому, когда срок действия билета аутентификации истекает, вызов метода страницы, очевидно, вызовет перенаправление на страницу входа.

Теперь гении, написавшие System.Web.Handlers.ScriptModule, решили, что если по какой-то причине вызов стиля REST для метода страницы или метода веб-службы из JavaScript вызывает перенаправление 302, они просто просто превратите ответ в 401 Несанкционированный. Это приводит к тому, что браузер отображает пользовательский интерфейс входа в систему, который вводит в заблуждение, поскольку пользователь пытается ввести свое имя пользователя и пароль, что ничего не значит, потому что используется FormsAuthentication. Наконец, когда пользователь нажимает кнопку Отмена, 401 обращается к обработчику ошибок.

Итак, вопрос в том, как можно отключить приглашение браузера для входа в систему каким-либо образом? Некоторые пользователи в Интернете предлагают использовать имя пользователя и пароль в запросе XHR, но, похоже, он не работает.

Ответы [ 3 ]

5 голосов
/ 12 декабря 2008

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

По сути, вы устанавливаете заголовок X-MicrosoftAjax на значение Delta = true (здесь важен регистр), ScriptModule будет интерпретировать это как нормальное перенаправление и превратите ответ в 200 , но задайте строку данных pageRedirect для любого ScriptManager (MS-AJAX PageRequestManager) на странице для использования. Функция jQuery.ajax по-прежнему будет воспринимать это как ошибку, поэтому в основном вы можете проверить pageRedirect в свойстве responseText XHR и соответствующим образом его обработать. Например, отправить пользователя на страницу входа в систему.

    $.ajax({
            type: "POST",
            url: postUrl + "/SomePageMethod",
            data: "{searchString:\"" + escape(searchString) + "\"}",
            contentType: "application/json; charset=utf-8",
            beforeSend: function(xhr) {
                xhr.setRequestHeader("X-MicrosoftAjax","Delta=true");
            },
            dataType: "json",
            success: onSuccess,
            error: onError
        });

function onError(xhr, e, textStatus) {
    var isAjaxRedirect = xhr.status == 200 && xhr.responseText.match(/pageRedirect/);
    if (isAjaxRedirect == "pageRedirect") {
        // forms authentication ticket expired
        location.href = "a session timeout page, or a login page or whatever";
    }
}
2 голосов
/ 23 марта 2012

Это можно отключить в IIS. Детали, описанные ниже, относятся к IIS6, но не составит труда найти соответствующие элементы для IIS7 и выше.

  1. Найдите соответствующий сайт.
  2. Откройте вкладку «Безопасность каталога» или соответствующую вкладку в вашей версии IIS
  3. Нажмите «Изменить» в разделе «Аутентификация и контроль доступа»
  4. Снять галочку «Интегрированная проверка подлинности Windows»

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

1 голос
/ 12 апреля 2014

Оба - отличные ответы. Но если ваш веб-сайт размещен на общем сервере, вы, вероятно, не сможете изменить настройки IIS, поэтому решение на стороне клиента будет успешным. Я столкнулся с той же проблемой, и этот пост спасает меня. Мои два цента на решение: В jquery (по крайней мере, в последних версиях) вы можете использовать параметр с именем «header» для отправки этих заголовков без использования обратного вызова «beforeSend», и я думаю, что это может быть немного более чистым способом сделать то же самое. Вы также можете добавить другую информацию заголовка здесь:

$.ajax({
            type: "POST",
            url: postUrl + "/SomePageMethod",
            data: "{searchString:\"" + escape(searchString) + "\"}",
            contentType: "application/json; charset=utf-8",
        headers: { "cache-control": "no-cache", "X-MicrosoftAjax" : "Delta=true" },
            dataType: "json",
            success: onSuccess,
            error: onError
        });

Я не знал об этом заголовке «Delta = true», а после небольшого исследования кажется, что это заголовок, который сообщает серверу, что ваш запрос является асинхронным запросом обратной передачи. .

Вызов AJAX вернет HTTP-статус 200 (вместо «Несанкционированный» 401) в обратном вызове «ошибка», что означает, что запрос сервера каким-то образом был успешным (хотя аутентификация не удалась). Немного странно, но так оно и работает.

Надеюсь, это поможет.

...