Подавить диалоговое окно NTLM после неавторизованного запроса

В недавнем проекте sharepoint я реализовал веб-часть аутентификации, которая должна заменить диалоговое окно аутентификации NTLM. Он работает нормально, пока пользователь предоставляет действительные учетные данные. Всякий раз, когда пользователь предоставляет неверные учетные данные, в Internet Explorer появляется диалоговое окно NTLM.

Мой код Javascript, который выполняет аутентификацию через XmlHttpRequest, выглядит следующим образом:

function Login() {
   var request = GetRequest(); // retrieves XmlHttpRequest
   request.onreadystatechange = function() {
      if (this.status == 401) {     // unauthorized request -> invalid credentials
         // do something to suppress NTLM dialog box...
         // already tried location.reload(); and window.location = <url to authentication form>;
      }
   }
   request.open("GET", "http://myServer", false, "domain\\username", "password");
   request.send(null);
}

Я не хочу, чтобы диалоговое окно NTLM отображалось, когда пользователь вводит неверные учетные данные. Вместо этого следует выполнить обратную передачу по кнопке входа в форму аутентификации. Другими словами, браузер не должен узнавать о моем несанкционированном запросе.

Есть ли способ сделать это через Javascript?

3 ответа

Решение

Комментарий Mark Brackett верен; Запрос на аутентификацию NTLM запускается кодом ответа 401 и присутствием NTLM в качестве первого механизма, предлагаемого в заголовке WWW-Authenticate (см.: Протокол аутентификации NTLM).

Я не уверен, правильно ли я понимаю описание вопроса, но я думаю, что вы пытаетесь обернуть проверку подлинности NTLM для SharePoint, что означает, что у вас нет контроля над протоколом проверки подлинности на стороне сервера, верно? Если вы не можете манипулировать серверной стороной, чтобы избежать отправки ответа 401 на ошибочные учетные данные, то вы не сможете избежать этой проблемы, поскольку она является частью спецификации (на стороне клиента):

Объект XMLHttpRequest

Если UA поддерживает аутентификацию HTTP [RFC2617], он ДОЛЖЕН рассматривать запросы, исходящие от этого объекта, как часть пространства защиты, которое включает в себя URI, к которым осуществляется доступ, и отправлять заголовки авторизации и обрабатывать 401 неавторизованные запросы соответствующим образом. в случае сбоя аутентификации UA должны запросить учетные данные у пользователей.

Таким образом, спецификация на самом деле требует от браузера соответствующего запроса пользователю, если какой-либо ответ 401 получен в XMLHttpRequest, так же, как если бы пользователь получил прямой доступ к URL. Насколько я могу сказать, единственный способ действительно избежать этого - это иметь контроль над серверной стороной и избежать 401 несанкционированных ответов, как отметил Марк.

Еще одна мысль: вы можете обойти это, используя прокси-сервер, такой как отдельный серверный скрипт на другом веб-сервере. Затем этот сценарий принимает параметр user и pass и проверяет аутентификацию, поэтому браузер пользователя не является тем, что делает исходный HTTP-запрос, и поэтому не получает ответ 401, который вызывает запрос. Если вы сделаете это таким образом, вы сможете узнать из сценария "прокси", что он потерпел неудачу, и если это так, то попросите пользователя снова, пока он не преуспеет. В случае успешного события аутентификации вы можете просто получить HTTP-запрос, как сейчас, так как все работает, если учетные данные указаны правильно.

IIRC, браузер открывает диалоговое окно авторизации, когда в поток запросов возвращается следующее:

  • Http статус 401
  • WWW-Authenticate header

Я предполагаю, что вам нужно подавить один или оба из них. Самый простой способ сделать это - использовать метод входа в систему, который будет принимать имя пользователя и пароль Base64 (вы используете HTTPS, верно?) И возвращать 200 с действительным / недействительным статусом. После того, как пароль был подтвержден, вы можете использовать его с XHR.

Я смог заставить это работать для всех браузеров, кроме Firefox. Смотрите мой блог ниже несколько лет назад. Мой пост нацелен только на IE, но с небольшими изменениями кода он должен работать в Chrome и Safari.

http://steve.thelineberrys.com/ntlm-login-with-anonymous-fallback-2/

РЕДАКТИРОВАТЬ:

Суть моего поста заключает в себе ваш вызов JS xml в оператор try catch. В IE, Chrome и Safari это отключит диалоговое окно NTLM. Кажется, он не работает так, как ожидалось в Firefox.

Другие вопросы по тегам