Как я могу подавить диалог аутентификации браузера?
Мое веб-приложение имеет страницу входа, которая отправляет учетные данные для аутентификации через вызов AJAX. Если пользователь вводит правильное имя пользователя и пароль, все в порядке, но если нет, происходит следующее:
- Веб-сервер определяет, что, хотя в запрос включен правильно сформированный заголовок авторизации, учетные данные в заголовке не проходят проверку подлинности.
- Веб-сервер возвращает код состояния 401 и включает в себя один или несколько заголовков WWW-Authenticate со списком поддерживаемых типов аутентификации.
- Браузер обнаруживает, что ответом на мой вызов объекта XMLHttpRequest является 401, и ответ включает заголовки WWW-Authenticate. Затем появляется диалоговое окно аутентификации с запросом имени пользователя и пароля.
Это все нормально вплоть до шага 3. Я не хочу, чтобы диалог всплывал, я хочу обработать ответ 401 в моей функции обратного вызова AJAX. (Например, отображая сообщение об ошибке на странице входа в систему.) Я хочу, чтобы пользователь повторно вводил свои имя пользователя и пароль, конечно, но я хочу, чтобы они увидели мою дружелюбную, обнадеживающую форму входа, а не уродливую браузерную, по умолчанию. диалог аутентификации.
Между прочим, я не имею никакого контроля над сервером, поэтому возвращение пользовательского кода состояния (т. Е. Чего-то другого, кроме 401) не вариант.
Есть ли способ подавить диалог аутентификации? В частности, могу ли я отключить диалог Требуется аутентификация в Firefox 2 или более поздней версии? Есть ли способ подавить диалог Connect to [host] в IE 6 и более поздних версиях?
редактировать
Дополнительная информация от автора (18 сентября):
Я должен добавить, что реальная проблема с диалоговым окном аутентификации браузера заключается в том, что он дает недостаточно информации пользователю.
Пользователь только что ввел имя пользователя и пароль через форму на странице входа в систему, он считает, что набрал их оба правильно, и он нажал кнопку отправки или нажал клавишу ввода. Он ожидает, что он перейдет на следующую страницу или, возможно, скажет, что он ввел свою информацию неправильно и должен повторить попытку. Однако вместо этого ему представляется неожиданное диалоговое окно.
Диалог не подтверждает тот факт, что он только что ввел имя пользователя и пароль. В нем четко не указано, что возникла проблема и что он должен попробовать еще раз. Вместо этого диалоговое окно предоставляет пользователю зашифрованную информацию, такую как "Сайт говорит:" [realm] "". Где [царство] - это короткое имя царства, которое может любить только программист.
Разработчики веб-броузера принимают к сведению: никто не спрашивал, как подавить диалог аутентификации, если бы сам диалог был просто более удобным для пользователя. Причина, по которой я заполняю форму входа, заключается в том, что наша команда по управлению продуктами справедливо считает, что диалоги аутентификации браузеров ужасны.
12 ответов
Я не думаю, что это возможно - если вы используете реализацию HTTP-клиента браузера, он всегда будет всплывать в этом диалоговом окне. На ум приходят два хака:
Может быть, Flash обрабатывает это по-другому (я еще не пробовал), так что использование Flash-фильма может помочь.
Вы можете настроить "прокси" для службы, к которой вы обращаетесь, на своем собственном сервере, и заставить ее немного изменить заголовки аутентификации, чтобы браузер не распознал их.
Я столкнулся с той же проблемой здесь, и бэкэнд-инженер в моей компании реализовал поведение, которое, по-видимому, считается хорошей практикой: когда при обращении к URL-адресу возвращается 401, если клиент установил заголовок X-Requested-With: XMLHttpRequest
сервер сбрасывает www-authenticate
Заголовок в своем ответе.
Побочным эффектом является то, что всплывающее окно аутентификации по умолчанию не появляется.
Убедитесь, что ваш вызов API имеет X-Requested-With
заголовок установлен в XMLHttpRequest
, Если это так, то ничего не нужно делать, кроме как изменить поведение сервера в соответствии с этой хорошей практикой...
В браузере появляется запрос на вход в систему, когда выполняются оба следующих условия:
- HTTP-статус 4xx
WWW-Authenticate
заголовок присутствует в ответе
Если вы можете контролировать ответ HTTP, то вы можете удалить WWW-Authenticate
заголовок из ответа, и браузер не будет отображать диалоговое окно входа в систему.
Если вы не можете контролировать ответ, вы можете настроить прокси для фильтрации WWW-Authenticate
Заголовок из ответа.
Насколько я знаю (не стесняйтесь исправлять меня, если я ошибаюсь), нет способа предотвратить приглашение входа в систему, как только браузер получит WWW-Authenticate
заголовок.
Я понимаю, что этот вопрос и его ответы очень старые. Но я оказался здесь. Возможно, другие тоже.
Если у вас есть доступ к коду для веб-службы, которая возвращает 401. Просто измените службу, чтобы вместо 403 возвращать 403 (Запрещено) в этой ситуации. Браузер не будет запрашивать учетные данные в ответ на 403. 403 является правильный код для аутентифицированного пользователя, который не авторизован для определенного ресурса. Что, кажется, ситуация ОП.
Из документа IETF по 403:
Сервер, который получает действительные учетные данные, не достаточные для получения доступа, должен ответить кодом состояния 403 (Запрещено).
В Mozilla вы можете достичь этого с помощью следующего скрипта при создании объекта XMLHttpRequest:
xmlHttp=new XMLHttpRequest();
xmlHttp.mozBackgroundRequest = true;
xmlHttp.open("GET",URL,true,USERNAME,PASSWORD);
xmlHttp.send(null);
2-я строка запрещает диалоговое окно....
Какую серверную технологию вы используете и какой конкретный продукт вы используете для аутентификации?
Поскольку браузер только выполняет свою работу, я считаю, что вы должны изменить ситуацию на стороне сервера, чтобы не возвращать код состояния 401. Это может быть сделано с помощью пользовательских форм аутентификации, которые просто возвращают форму снова, когда аутентификация не проходит.
В Mozilla Land установка true для параметра mozBackgroundRequest XMLHttpRequest ( docs) подавляет эти диалоги и приводит к просто сбоям запросов. Однако я не знаю, насколько хороша межбраузерная поддержка (в том числе, действительно ли качество информации об ошибках в тех неудачных запросах очень хорошо во всех браузерах).
У jan.vdbergh есть правда: если вы можете изменить 401 на стороне сервера на другой код состояния, браузер не поймает и не раскрасит всплывающее окно. Другим решением может быть изменение заголовка WWW-Authenticate для другого настраиваемого заголовка. Я не верю, почему другой браузер не может его поддерживать, в нескольких версиях Firefox мы можем выполнить запрос xhr с помощью mozBackgroundRequest, но в других браузерах?? Здесь есть интересная ссылка с этой проблемой в Chromium.
У меня та же проблема с 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");
Пока это работало нормально, и я должен сообщить вам, что я все еще тестирую его, и у приведенного выше кода нет причин для запуска, поэтому он подлежит удалению... тестирование в настоящее время включает в себя попытку обнаружить случай, когда второй набор кода больше не нужен. Опять же, эта работа еще не завершена, но, поскольку она может оказать некоторую помощь или потрясти ваш мозг некоторыми идеями, я решил добавить ее сейчас... Я обновлю ее с окончательными результатами после завершения всех испытаний.
Недавно я столкнулся с подобной ситуацией при разработке веб-приложения для Samsung Tizen Smart TV. Требовалось просканировать всю локальную сеть, но несколько IP-адресов возвращали ответ «401 Unauthorized» с прикрепленным заголовком «www-authenticate». Появлялось всплывающее окно аутентификации браузера, требующее от пользователя ввода «Имя пользователя» и «Пароль» из-за «Базового» типа аутентификации (https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication).
Чтобы избавиться от этого, простая вещь, которая сработала для меня, — это установка учетных данных: «опустить» для вызова Fetc Api (https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch). Официальная документация говорит, что:
Вместо этого, чтобы браузеры не включали учетные данные в запрос, используйте учетные данные: 'опустить'
Я использую Node, Express & Passport и боролся с той же проблемой. Я получил его на работу, явно установив www-authenticate
заголовок пустой строки. В моем случае это выглядело так:
(err, req, res, next) => {
if (err) {
res._headers['www-authenticate'] = ''
return res.json(err)
}
}
Я надеюсь, что это помогает кому-то!
Для тех, кто не знаком с C#, вот ActionAttribute
это возвращает 400
вместо 401
и 'глотает' диалог основного входа.
public class NoBasicAuthDialogAuthorizeAttribute : AuthorizeAttribute
{
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
base.HandleUnauthorizedRequest(filterContext);
filterContext.Result = new HttpStatusCodeResult(400);
}
}
используйте как следующее:
[NoBasicAuthDialogAuthorize(Roles = "A-Team")]
public ActionResult CarType()
{
// your code goes here
}
Надеюсь, это сэкономит вам время.