如何从 AJAX 调用触发浏览器的基本身份验证对话框?

Posted

技术标签:

【中文标题】如何从 AJAX 调用触发浏览器的基本身份验证对话框?【英文标题】:How do I trigger the browser's Basic Authentication dialog from an AJAX call? 【发布时间】:2015-01-07 02:29:21 【问题描述】:

我正在使用基本身份验证来保护仅在我们公司网络内公开的一组 WCF Web 服务,我想知道是否有办法在 Web 服务返回时触发浏览器的凭据对话框从 AJAX 调用中出现出现 401 错误?

目前,我的 AJAX 调用将 401 作为常规失败请求接收,并且不会提示浏览器执行任何操作。但是,如果我采用相同的 URI 并将其复制粘贴到浏览器的 URL 栏中,则返回的 401 会正确触发基本身份验证对话框。

有没有办法让 AJAX 回调告诉浏览器弹出那个对话框?

【问题讨论】:

它应该会在需要时自动弹出,即使是从不可见的 ajax 代码中。你可能需要一个更具体的 ajax 错误处理程序 【参考方案1】:

使用您的 url 动态创建 iframe 并附加到文档。它将触发身份验证表单。 jQuery snipet 添加 iframe

$('<iframe src="your_url"></iframe>').appendTo('body')

这里有一个非常简化的例子:

var url = 'your_url_here';
$.ajax(
    url: url,
    error: function(response)
        if(response.status==401)           
            $('<iframe src="'+url+'"></iframe>').appendTo('body');          
        
    ,
    success:function()
        //your success code here
    
);

【讨论】:

有没有办法更好地管理这里的上下文?也许是为了获取 iframe 中传递的数据并将其推回成功函数?我宁愿保持 iframe 不可见。 也许也支持 POST 方法? @jab 如果您使 iframe 不可见,浏览器可能不会发出任何请求,因此没有身份验证对话框。最好将其设置为 1x1 像素或使用绝对位置,并使用非常大的顶部和左侧使其从文档视图端口消失。从 iframe 将数据推送到成功函数的一种方法是使成功函数全局可访问并从 iframe 中调用它,例如 window.top.success(data)【参考方案2】:

我遇到了几乎相同的 401 问题,除了我的请求是跨域的。但我希望原因是一样的。按照developer.mozilla - Access control CORS上的说明,我终于成功了:

var xhttp=new XMLHttpRequest();
xhttp.withCredentials = true;
xhttp.open("GET", "https://my.foo.server/app/resource", true);
xhttp.send();

我认为xhttp.withCredentials 是解决方案。这不是标题!您让浏览器通过 cookie 与服务器通信。下面的回答解释了很多XHR2 withCredentials - which cookies are sent?

没有xhttp.withCredentials,总是有401 (Unauthorized)。但是使用它时,浏览器会添加所需的标头 Authorization:Basic dGVFooFooFooFoosaWVudA==触发登录对话框,此时凭据尚不可用。

【讨论】:

我在使用 axios 时遇到了同样的问题,这个答案直接让我找到了类似的 withCredentials 配置。【参考方案3】:

您不能,您需要向请求提供凭据。

见How to use Basic Auth with jQuery and AJAX?

【讨论】:

它没有回答它只是建议使用它的评论【参考方案4】:

您建议打开/显示/插入表单以允许插入用户名和密码,然后使用给定凭据重新发送 AJAX 请求。我不会真的在浏览器凭据弹出窗口上。

如何设置身份验证标头,您可以在此处阅读:How to use Basic Auth with jQuery and AJAX?

【讨论】:

【参考方案5】:

是的,您可以从 AJAX 调用它。只需使用以下标头传递请求:

withCredentials: true

【讨论】:

【参考方案6】:

在堆栈中的某处找到:

收到 401 响应是服务器告诉你,“你不是 已认证 - 完全未认证或已认证 不正确 - 但请重新验证并重试。”为了帮助你, 它将始终包含一个 WWW-Authenticate 标头,该标头描述如何 验证

使用 jQuery 的 beforeSend 回调添加带有身份验证信息的 HTTP 标头

beforeSend: function (xhr) 
xhr.setRequestHeader ("Authorization", "Basic " + btoa(username + ":" + password));
,

【讨论】:

【参考方案7】:

您是否满足this SO answer?中突出显示的条件

同样基于in this other answer,您可能需要检查从后端返回的标头是否相同,无论您是从浏览器还是从 AJAX 调用请求。

【讨论】:

标头是一样的,我总是回传WWW-authenticate,不管是什么类型的请求,认证不成功。在这种情况下,我可以完全控制服务器,因此我可以在必要时返回额外的标头。 我明白了,我不确定问题是什么,我已经看到以前使用 pouchDB / couchDB,我可以整理一个小例子 你能在 plunkr 上创建一个小例子,我可以看看吗?【参考方案8】:

您可以在检查 401 条件时触发重定向:

window.location = "https://example.com"

【讨论】:

以上是关于如何从 AJAX 调用触发浏览器的基本身份验证对话框?的主要内容,如果未能解决你的问题,请参考以下文章

使用 jQuery 和 Ajax 进行基本身份验证

为啥 Chrome 和 Firefox 使用基本身份验证的 CORS ajax 调用的行为不同?

更改 Restlet 发回的状态码以进行身份​​验证

如何从控制器调用身份验证 - 弹簧安全核心插件

使用 AngularJS 拦截器阻止 HTTP 基本身份验证对话框

AD FS 2.0 身份验证和 AJAX