如何防止浏览器调用基本的验证弹出窗口并使用Jquery处理401错误
How to prevent browser to invoke basic auth popup and handle 401 error using Jquery?
我需要使用基本身份验证发送授权请求。我已经使用jquery成功地实现了这一点。然而,当我收到401错误时,基本的auth浏览器弹出窗口被打开,jquery ajax错误回调没有被调用。
我最近也遇到了这个问题。由于在401
(基本或摘要身份验证)的情况下,您无法更改浏览器显示弹出窗口的默认行为,因此有两种方法可以解决此问题:
- 将服务器响应更改为不返回
401
。返回一个200
代码,并在jQuery客户端中进行处理 -
将用于授权的方法更改为标头中的自定义值。浏览器将显示基本和摘要的弹出窗口。您必须在客户端和服务器上都对此进行更改。
headers : { "Authorization" : "BasicCustom" }
还请看一下这个例子,以获得将jQuery与Basic Auth一起使用的例子。
返回一个通用的400状态代码,然后处理该客户端。
或者,您可以保留401,而不返回WWW-Authenticate标头,这正是浏览器通过身份验证弹出窗口所响应的。如果WWW-Authenticate标头丢失,则浏览器不会提示输入凭据。
正如其他人所指出的,更改浏览器行为的唯一方法是确保响应不包含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
模块。(在Debian/Ubuuntu上,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>
您可以使用如下所示的请求url来抑制基本身份验证弹出窗口:
https://username:password@example.com/admin/...
如果您收到401错误(用户名或密码错误),jquery错误回调将正确处理。它可能会导致一些安全问题(在http协议而不是https的情况下),但它是有效的。
UPD:此解决方案支持将在Chrome 59 中删除
在请求标头中使用X-Requested-With:XMLHttpRequest。因此,响应标头将不包含WWW-Authenticate:Basic。
beforeSend: function (xhr) {
xhr.setRequestHeader('Authorization', ("Basic "
.concat(btoa(key))));
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
},
如果使用IIS服务器,可以设置IIS URL重写(v2),将请求的URL上的WWW-Authentication
标头重写为None
。
在这里指导。
要更改的值为response_www_authenticate
。
如果你需要更多信息,请添加评论,我会发布web.config文件。
如果WWW-Authenticate标头被删除,那么您将无法缓存凭据,也无法在请求中返回Authorization标头。这意味着现在您必须为生成的每个新请求输入凭据。
我还没有探究修复的原因或范围,但我发现如果我正在执行fetch
请求,并添加标题x-requested-with: 'XMLHttpRequest'
,我将不再在Chrome中获得弹出验证框,也不需要更改服务器。它正在与节点http
库对话。看起来WWW-Authenticate
标头是从服务器返回的,但Chrome对它的处理方式不同。可能是规格。
示例:
fetch(url, {
headers: {
Authorization: `Basic ${auth}`,
'x-requested-with': 'XMLHttpRequest'
},
credentials: 'include'
})
或者,如果您可以自定义服务器响应,则可以返回403 Forbidden。
浏览器将不会打开身份验证弹出窗口,并且将调用jquery回调。
在Safari中,您可以使用同步请求来避免浏览器显示弹出窗口。当然,同步请求只应在这种情况下用于检查用户凭据。。。您可以在发送实际请求之前使用这样的请求,如果内容(发送或接收)非常重,这可能会导致糟糕的用户体验。
var xmlhttp=new XMLHttpRequest;
xmlhttp.withCredentials=true;
xmlhttp.open("POST",<YOUR UR>,false,username,password);
xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xmlhttp.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
创建/login-url,然后通过GET接受"用户"answers"密码"参数,并且不需要基本的身份验证。在这里,使用php、node、java等,解析您的passwd文件并根据它匹配参数(user/pass)http://user:pass@domain.com/(这将在您的浏览器上设置凭据)如果没有,则发送401响应(无WWW-Authenticate标头)。
在Spring Boot的背面,我使用了自定义的BasicAuthenticationEntryPoint:
@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and().authorizeRequests()
...
.antMatchers(PUBLIC_AUTH).permitAll()
.and().httpBasic()
// https://www.baeldung.com/spring-security-basic-authentication
.authenticationEntryPoint(authBasicAuthenticationEntryPoint())
...
@Bean
public BasicAuthenticationEntryPoint authBasicAuthenticationEntryPoint() {
return new BasicAuthenticationEntryPoint() {
{
setRealmName("pirsApp");
}
@Override
public void commence
(HttpServletRequest request, HttpServletResponse response, AuthenticationException authEx)
throws IOException, ServletException {
if (request.getRequestURI().equals(PUBLIC_AUTH)) {
response.sendError(HttpStatus.PRECONDITION_FAILED.value(), "Wrong credentials");
} else {
super.commence(request, response, authEx);
}
}
};
}
- 为什么不是't窗口.恢复正常工作吗?(javascript/jquery)
- 基于窗口宽度jquery的函数的替代方法是什么
- Jquery Onclick将数据发送到新打开的窗口
- jQuery调整大小函数只适用于窗口
- 是否可以使用Jquery操作窗体的目标窗口
- 使用jQuery可以根据窗口大小更改滑块的css高度
- 弹出窗口-jQuery Mobile、Backbone.js和Require.js
- 如何将文本框弹出窗口(Jquery 工具提示或类似工具)添加到画布中的 Fabric JS 图像
- 如何在点击弹出窗口jQuery内应用悬停效果
- 如何关闭模型弹出窗口jquery
- 从新打开的窗口jquery中删除一个节点
- 可拖动的非模态弹出窗口Jquery Mobile
- 在弹出窗口Jquery(灯箱)中打开照片
- 将Modal定位到当前窗口-jQuery
- 什么是窗口?jQuery和窗口.美元的意思
- 在新的窗口jquery功能不工作
- 警告中心元素窗口(jQuery)
- 条形码扫描器触发下一个按钮点击事件和弹出窗口JQuery
- 如何从另一个弹出窗口中的链接调用弹出窗口.Jquery Mobile
- 如何重用剑道ui窗口jquery