如何防止浏览器调用基本身份验证弹出窗口并使用 Jquery 处理 401 错误?

IT技术 javascript jquery rest basic-authentication
2021-03-02 05:36:21

我需要使用基本身份验证发送授权请求。我已经使用 jquery 成功实现了这一点。但是,当我收到 401 错误时,基本身份验证浏览器弹出窗口已打开并且未调用 jquery ajax 错误回调。

6个回答

我最近也面临这个问题。由于您无法更改浏览器在401基本摘要式身份验证)情况下显示弹出窗口的默认行为,因此有两种方法可以解决此问题:

  • 将服务器响应更改为不返回401. 200而是返回一个代码并在您的 jQuery 客户端中处理它。
  • 将您用于授权的方法更改为标头中的自定义值。浏览器将显示BasicDigest的弹出窗口您必须在客户端和服务器上更改此设置。

    headers : {
      "Authorization" : "BasicCustom"
    }
    

另请查看示例,以了解将 jQuery 与基本身份验证一起使用的示例。

WWW-Authenticate:xBasic realm=com.example 可以做到,再加上经典的401状态码。这篇博文向我展示了提示(我不是博客的所有者)loudvchar.blogspot.ca/2010/11/...
2021-04-15 05:36:21
@PM,博客的答案是一个完美的解决方案。请注意,如果使用<security:http-basic/>,则不需要定义,basicAuthenticationFilter但应将其定义为<security:http-basic entry-point-ref="myBasicAuthenticationEntryPoint"/>.
2021-04-28 05:36:21
出于某种原因,我得到返回时弹出401WWW-Authenticate:Bearer WWW-Authenticate:NTLM WWW-Authenticate:Negotiate你们知道为什么,这将是
2021-05-07 05:36:21
你能告诉我如何在发送回客户端之前覆盖响应吗,我正在使用带有基本身份验证的 jaxrs。我需要重写哪个类来修改响应?
2021-05-14 05:36:21
@PM 仅供参考此方法在当前的 Chrome 版本中不再适用
2021-05-14 05:36:21

返回一个通用的 400 状态代码,然后处理该客户端。

或者您可以保留 401,而不返回 WWW-Authenticate 标头,这实际上是浏览器通过身份验证弹出窗口响应的内容。如果缺少 WWW-Authenticate 标头,则浏览器将不会提示输入凭据。

@MortenHaraldsen 好吧,401 响应是在这种情况下给出的正确响应,问题是浏览器会自动在本机处理它,而不是允许 javascript 应用程序处理它。您可以通过不返回标准推荐的正确响应来坚持标准,或者您可以选择不遵循标准,通过返回标准推荐的响应代码。随你选择:)
2021-04-23 05:36:21
@Ibraheem,我自己说得再好不过了。标准是由坐下来交谈的人创建的,不一定是坐下来编写代码的人。
2021-04-24 05:36:21
在我的快递应用程序中,我用一行解决了这个问题: res.removeHeader('www-authenticate'); // prevents browser from popping up a basic auth window.
2021-05-04 05:36:21
@Ibraheem 不适用于当前的 Chrome 浏览器。无论如何要绕过这个吗?
2021-05-13 05:36:21

您可以使用如下所示的请求 url 来抑制基本身份验证弹出窗口:

https://username:password@example.com/admin/...

如果您收到 401 错误(错误的用户名或密码),它将被 jquery 错误回调正确处理。它可能会导致一些安全问题(在 http 协议而不是 https 的情况下),但它有效。

UPD:此解决方案支持将在 Chrome 59 中删除

请不要这样做,您的网络服务器上的请求日志现在对我来说更有value.. 免费用户名和密码组合以及响应代码!谢谢
2021-04-19 05:36:21
但是如何防止用户名和密码被查看
2021-04-21 05:36:21
惊人!!!!解决了我的问题,因为问题是在尝试 192.168.1.1 并且路由器不断要求身份验证。
2021-04-29 05:36:21
如果您转到开发人员工具下的“网络”选项卡,在任何浏览器中,您都可以以纯文本形式读取用户名和密码。不过,它有效。
2021-04-30 05:36:21
这种身份验证方法正在贬值,Chrome 将https://user:pass@host/在 2017 年 6 月左右放弃对嵌入式凭据的支持,即在 M59 中。有关更多信息,请参阅此 chromestatus 博客文章
2021-05-11 05:36:21

正如其他人指出的那样,更改浏览器行为的唯一方法是确保响应不包含 401 状态代码,或者如果包含,则不包含WWW-Authenticate: Basic标题。由于更改状态代码不是很符合语义且不可取,因此删除WWW-Authenticate标头是一个好方法如果您不能或不想修改您的 Web 服务器应用程序,您始终可以通过 Apache 为其提供服务或代理(如果您尚未使用 Apache)。

这是 Apache 重写响应以删除 WWW-Authenticate 标头的配置,请求包含的 IFF 包含标头X-Requested-With: XMLHttpRequest(默认情况下由 JQuery/AngularJS 等主要 Javascript 框架设置...)并且响应包含标题WWW-Authenticate: Basic

在 Apache 2.4 上测试(不确定它是否适用于 2.2)。这取决于mod_headers正在安装module。(在 Debian/Ubuntu 上,sudo a2enmod headers并重新启动 Apache)

    <Location />
            # Make sure that if it is an XHR request,
            # we don't send back basic authentication header.
            # This is to prevent the browser from displaying a basic auth login dialog.
            Header unset WWW-Authenticate "expr=req('X-Requested-With') == 'XMLHttpRequest' && resp('WWW-Authenticate') =~ /^Basic/"
    </Location>   
@syastrov 不适用于当前的 Chrome 版本
2021-04-27 05:36:21
要对 Nginx 执行相同操作,请设置 proxy_hide_header WWW-Authenticate;
2021-05-02 05:36:21

将 X-Requested-With: XMLHttpRequest 与您的请求标头一起使用。所以响应头将不包含 WWW-Authenticate:Basic。

beforeSend: function (xhr) {
                    xhr.setRequestHeader('Authorization', ("Basic "
                        .concat(btoa(key))));
                    xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
                },
@RobertAntonucci 这是 apache tomcat
2021-05-09 05:36:21
那对我没有影响。当您设置 XMLHttpRequest 时,您使用的是什么类型的服务器,不包括发送 WWW-Authenticate?
2021-05-12 05:36:21