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

StackOverflow https://stackoverflow.com/questions/29680

  •  09-06-2019
  •  | 
  •  

Вопрос

В недавнем проекте 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?

Это было полезно?

Решение

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

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

Объект XMLHttpRequest

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

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

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

Другие советы

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

  • HTTP-статус 401
  • Заголовок WWW-аутентификации

Я предполагаю, что вам придется подавить один или оба из них.Самый простой способ сделать это — иметь метод входа в систему, который будет принимать имя пользователя и пароль 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 это не работает должным образом.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top