Как я могу подавить диалог аутентификации браузера? - PullRequest
74 голосов
/ 17 сентября 2008

Мое веб-приложение имеет страницу входа, которая отправляет учетные данные для аутентификации через вызов AJAX. Если пользователь вводит правильное имя пользователя и пароль, все в порядке, но если нет, происходит следующее:

  1. Веб-сервер определяет, что, хотя в запрос включен правильно сформированный заголовок авторизации, учетные данные в заголовке не проходят проверку подлинности.
  2. Веб-сервер возвращает код состояния 401 и включает в себя один или несколько заголовков WWW-Authenticate со списком поддерживаемых типов аутентификации.
  3. Браузер обнаруживает, что ответом на мой вызов объекта XMLHttpRequest является 401, и ответ включает заголовки WWW-Authenticate. Затем появляется диалоговое окно аутентификации с запросом имени пользователя и пароля.

Это нормально до шага 3. Я не хочу, чтобы диалоговое окно всплывало, я хочу обработать ответ 401 в моей функции обратного вызова AJAX. (Например, отображая сообщение об ошибке на странице входа в систему.) Я хочу, чтобы пользователь повторно вводил свои имя пользователя и пароль, конечно, но я хочу, чтобы они увидели мою дружественную, обнадеживающую форму входа в систему, а не уродливый браузер, по умолчанию диалог аутентификации.

Между прочим, я не имею никакого контроля над сервером, поэтому заставить его возвращать пользовательский код состояния (т. Е. Что-то отличное от 401) не вариант.

Есть ли способ подавить диалог аутентификации? В частности, можно ли отключить диалоговое окно «Требуется аутентификация» в Firefox 2 или более поздней версии? Есть ли способ подавить диалог Connect to [host] в IE 6 и более поздних версиях?


Редактировать
Дополнительная информация от автора (18 сентября):
Я должен добавить, что реальная проблема с диалоговым окном аутентификации браузера заключается в том, что он дает недостаточно информации пользователю.

Пользователь только что ввел имя пользователя и пароль через форму на странице входа в систему, он считает, что набрал их оба правильно, и он нажал кнопку отправки или нажал клавишу ввода. Он ожидает, что он перейдет на следующую страницу или, возможно, скажет, что он ввел свою информацию неправильно и должен повторить попытку. Однако вместо этого ему представляется неожиданное диалоговое окно.

Диалог не подтверждает тот факт, что он просто сделал , введя имя пользователя и пароль. В нем четко не указано, что возникла проблема и что он должен попробовать еще раз. Вместо этого диалоговое окно предоставляет пользователю зашифрованную информацию, такую ​​как «Сайт говорит:« [realm] '». Где [realm] - это короткое имя области, которое может любить только программист.

Дизайнеры веб-браузеров принимают к сведению: никто не спрашивал, как подавить диалог аутентификации, если бы сам диалог был просто более удобным для пользователя. вся причина, по которой я заполняю форму входа, состоит в том, что наша команда по управлению продуктами справедливо считает, что диалоги аутентификации браузеров ужасны.

Ответы [ 11 ]

46 голосов
/ 26 ноября 2013

Я столкнулся с той же проблемой здесь, и бэкэнд-инженер в моей компании реализовал поведение, которое, очевидно, считается хорошей практикой: когда при обращении к URL-адресу возвращается 401, если клиент установил заголовок X-Requested-With: XMLHttpRequest, сервер отбрасывает заголовок www-authenticate в своем ответе.

Побочным эффектом является то, что всплывающее окно аутентификации по умолчанию не появляется.

Убедитесь, что для вашего вызова API установлен заголовок X-Requested-With, равный XMLHttpRequest. Если это так, ничего не нужно делать, кроме как изменить поведение сервера в соответствии с этой хорошей практикой ...

17 голосов
/ 18 сентября 2008

Я не думаю, что это возможно - если вы используете реализацию HTTP-клиента браузера, он всегда будет отображаться в этом диалоговом окне. На ум приходят два хака:

  1. Может быть, Flash обрабатывает это по-другому (я еще не пробовал), поэтому использование флэш-фильма может помочь.

  2. Вы можете установить «прокси» для службы, к которой вы обращаетесь, на своем собственном сервере, и заставить ее немного изменить заголовки аутентификации, чтобы браузер не распознал их.

14 голосов
/ 16 марта 2015

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

  1. HTTP-статус 4xx
  2. WWW-Authenticate заголовок присутствует в ответе

Если вы можете контролировать HTTP-ответ, вы можете удалить заголовок WWW-Authenticate из ответа, и браузер не будет отображать диалоговое окно входа в систему.

Если вы не можете контролировать ответ, вы можете настроить прокси-сервер для фильтрации заголовка WWW-Authenticate из ответа.

Насколько я знаю (не стесняйтесь исправлять меня, если я ошибаюсь), невозможно запретить вход в систему после получения браузером заголовка WWW-Authenticate.

5 голосов
/ 05 октября 2016

Я понимаю, что этот вопрос и его ответы очень стары. Но я оказался здесь. Возможно, другие тоже.

Если у вас есть доступ к коду веб-службы, которая возвращает 401. Просто измените службу, чтобы в этой ситуации вместо 403 возвращалось 403 (Запрещено). Браузер не будет запрашивать учетные данные в ответ на 403. 403 является правильным кодом для аутентифицированного пользователя, который не авторизован для конкретного ресурса. Который, кажется, ситуация ОП.

Из документа IETF по 403:

Сервер, который получает действительные учетные данные, которые не соответствуют Для получения доступа необходимо ответить кодом состояния 403 (Запрещено)

4 голосов
/ 04 октября 2008

В Mozilla вы можете достичь этого с помощью следующего скрипта при создании объекта XMLHttpRequest:

xmlHttp=new XMLHttpRequest();
xmlHttp.mozBackgroundRequest = true;
xmlHttp.open("GET",URL,true,USERNAME,PASSWORD);
xmlHttp.send(null);

2-я строка запрещает диалоговое окно ....

2 голосов
/ 26 июля 2012

jan.vdbergh имеет правду, если вы можете изменить 401 на стороне сервера для другого кода состояния, браузер не поймает и раскрасит всплывающее окно. Другим решением может быть изменение заголовка WWW-Authenticate для другого настраиваемого заголовка. Я не верю, почему другой браузер не может его поддерживать, в нескольких версиях Firefox мы можем выполнить запрос xhr с помощью mozBackgroundRequest, но в других браузерах ?? здесь есть интересная ссылка с этой проблемой в Chromium.

2 голосов
/ 30 января 2009

В земле Mozilla установка параметра mozBackgroundRequest XMLHttpRequest ( docs ) в значение true подавляет эти диалоги и приводит к тому, что запросы просто не выполняются. Тем не менее, я не знаю, насколько хороша межбраузерная поддержка (включая то, насколько качество информации об ошибках в тех неудачных запросах очень хорошо во всех браузерах.)

2 голосов
/ 17 сентября 2008

Какую серверную технологию вы используете и какой конкретный продукт вы используете для аутентификации?

Поскольку браузер только выполняет свою работу, я полагаю, что вы должны изменить ситуацию на стороне сервера, чтобы не возвращать код состояния 401. Это можно сделать с помощью пользовательских форм аутентификации, которые просто возвращают форму снова, когда аутентификация не удалась.

1 голос
/ 28 мая 2015

У меня такая же проблема с MVC 5 и VPN, когда всякий раз, когда мы находимся за пределами DMZ, используя VPN, мы вынуждены отвечать на это сообщение браузера. Используя .net, я просто обрабатываю маршрутизацию ошибки, используя

<customErrors defaultRedirect="~/Error"  >
  <error statusCode="401" redirect="~/Index"/>
</customErrors>

до сих пор это работало, потому что действие Index под домашним контроллером проверяет пользователя. Представление в этом действии, если вход в систему неуспешен, имеет элементы управления входом, которые я использую для входа пользователя, используя запрос LDAP, переданный в службы каталогов:

      DirectoryEntry entry = new DirectoryEntry("LDAP://OurDomain");
      DirectorySearcher Dsearch = new DirectorySearcher(entry);
      Dsearch.Filter = "(SAMAccountName=" + UserID + ")";
      Dsearch.PropertiesToLoad.Add("cn");

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

0 голосов
/ 18 октября 2017

Я использую Node, Express & Passport и боролся с той же проблемой. Я заставил его работать, явно установив заголовок www-authenticate в пустую строку. В моем случае это выглядело так:

(err, req, res, next) => {
  if (err) {
    res._headers['www-authenticate'] = ''
    return res.json(err)
  }
}

Надеюсь, это кому-нибудь поможет!

...