如何抑制浏览器的身份验证对话框?

IT技术 javascript ajax http-authentication
2021-01-16 23:54:28

我的 Web 应用程序有一个登录页面,该页面通过 AJAX 调用提交身份验证凭据。如果用户输入正确的用户名和密码,则一切正常,但如果没有,则会发生以下情况:

  1. Web 服务器确定虽然请求包含格式正确的 Authorization 标头,但标头中的凭据未成功验证。
  2. Web 服务器返回 401 状态代码并包含一个或多个 WWW-Authenticate 标头,其中列出了支持的身份验证类型。
  3. 浏览器检测到我对 XMLHttpRequest 对象的调用的响应是 401,并且响应包括 WWW-Authenticate 标头。然后它会弹出一个身份验证对话框,再次询问用户名和密码。

这一切都很好,直到第 3 步。我不想弹出对话框,我想在我的 AJAX 回调函数中处理 401 响应。(例如,通过在登录页面上显示错误消息。)当然,我希望用户重新输入他们的用户名和密码,但我希望他们看到我友好、令人放心的登录表单,而不是浏览器的丑陋、默认身份验证对话框。

顺便说一句,我无法控制服务器,因此不能选择让它返回自定义状态代码(即 401 以外的其他代码)。

有什么办法可以取消身份验证对话框吗?特别是,我可以在 Firefox 2 或更高版本中取消“需要身份验证”对话框吗?有没有办法在 IE 6 及更高版本中抑制连接到[host]对话框?


编辑
来自作者的附加信息(9 月 18 日):
我应该补充一点,浏览器弹出的身份验证对话框的真正问题在于它向用户提供的信息不足。

用户刚刚通过登录页面上的表单输入了用户名和密码,他相信他已经正确输入了它们,并且他点击了提交按钮或按下了回车键。他的期望是他将被带到下一页,或者可能被告知他输入的信息不正确,应该再试一次。然而,他看到的是一个意想不到的对话框。

对话是没有的,他只是一个事实确认没有输入用户名和密码。它没有明确说明存在问题,他应该再试一次。取而代之的是,该对话框向用户展示了诸如“站点说:' [领域] '”之类的神秘信息其中[realm]是一个简短的领域名称,只有程序员才会喜欢。

Web 浏览器设计者注意到:如果对话框本身对用户更友好,那么没有人会问如何抑制身份验证对话框。我使用登录表单全部原因是我们的产品管理团队正确地认为浏览器的身份验证对话框很糟糕。

6个回答

我在这里遇到了同样的问题,我公司的后端工程师实施了一种显然被认为是一种很好的做法的行为:当对 URL 的调用返回 401 时,如果客户端设置了标头X-Requested-With: XMLHttpRequest,则服务器将www-authenticate标头放入其回复。

副作用是不会出现默认的身份验证弹出窗口。

确保您的 API 调用将X-Requested-With标头设置为XMLHttpRequest. 如果是这样,除了根据此良好做法更改服务器行为外,别无他法...

这次真是万分感谢。许多图书馆都采用了这种行为,包括设计
2021-03-20 23:54:28
知道如何在 nginx 中做到这一点吗?“当对 URL 的调用返回 401 时,如果客户端设置了 X-Requested-With: XMLHttpRequest 标头,服务器会在其响应中丢弃 www-authenticate 标头。”
2021-03-31 23:54:28
如果后端是基于 Java/Spring 的,DelegatingAuthenticationEntryPoint它会为您处理此行为。
2021-04-06 23:54:28

当同时满足以下两个条件时,浏览器会弹出登录提示:

  1. HTTP 状态为 401
  2. WWW-Authenticate 响应中存在标头

如果您可以控制 HTTP 响应,那么您可以WWW-Authenticate从响应中删除标头,浏览器不会弹出登录对话框。

如果您无法控制响应,则可以设置代理以WWW-Authenticate从响应中过滤掉标头。

据我所知(如果我错了,请随时纠正我),一旦浏览器收到WWW-Authenticate标题,就无法阻止登录提示

好资料。关于有效的WWW-Authenticate标头值,请参阅stackoverflow.com/a/1748451/225217
2021-03-18 23:54:28

我认为这是不可能的——如果你使用浏览器的 HTTP 客户端实现,它总是会弹出那个对话框。想到了两个黑客:

  1. 也许 Flash 处理这个的方式不同(我还没有尝试过),所以让 Flash 电影提出请求可能会有所帮助。

  2. 您可以为您在自己的服务器上访问的服务设置一个“代理”,并让它稍微修改身份验证标头,以便浏览器无法识别它们。

我尝试通过以下代码捕获未经授权的 401 错误: $.ajaxSetup({ statusCode: { 401: function () { RedirectToLogin(); } } }); 但是 IE 总是显示浏览器的身份验证对话框。我如何在 ASP.Net MVC 2 中抑制这个对话框?
2021-03-17 23:54:28
@dgvid 抱歉,但“不可能”让我不理智地生气。我知道计算机可以做什么,而且这绝对是可能的,这让我对设计它的人不提供这种功能感到愤怒。
2021-03-19 23:54:28
“不可能”似乎是正确答案,尽管我怀疑“代理”黑客可以解决问题。
2021-04-03 23:54:28
@7SpecialGems 好收获。我并不是在暗示这是一个骗局,我链接到了在接受答案 4 年后发布的特定答案(WWW-Authenticate 答案)。虽然事后看来,我不记得我为什么看那个,或者我是如何测试它的。
2021-04-10 23:54:28
@Stobor 您发布的重复项的公认答案实际上链接回此问题作为其答案!
2021-04-12 23:54:28

我意识到这个问题及其答案非常古老。但是,我终于到了这里。也许其他人也会。

如果您有权访问返回 401 的 Web 服务的代码。在这种情况下,只需将服务更改为返回 403(禁止)而不是 401。浏览器不会提示输入凭据以响应 403。403 是未授权使用特定资源的已验证用户的正确代码。这似乎是OP的情况。

来自 403 的 IETF 文档:

收到不足以获得访问权限的有效凭据的服务器应该以 403(禁止)状态代码响应

在 Mozilla 中,您可以在创建 XMLHttpRequest 对象时使用以下脚本实现它:

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

第二行阻止对话框....

这在 Firefox 2 下似乎没有任何作用。它导致 DOM 安全错误,在 Firefox 3 下,NS_ERROR_DOM_SECURITY_ERR 代码 1000。
2021-03-23 23:54:28