在最近的一个共享点项目中,我实现了一个身份验证 Web 部件,它应该取代 NTLM 身份验证对话框。只要用户提供有效的凭据,它就可以正常工作。每当用户提供无效凭据时,Internet Explorer 中就会弹出 NTLM 对话框。

我的 Javascript 代码通过 XmlHttpRequest 进行身份验证,如下所示:

function Login() {
   var request = GetRequest(); // retrieves XmlHttpRequest
   request.onreadystatechange = function() {
      if (this.status == 401) {     // unauthorized request -> invalid credentials
         // do something to suppress NTLM dialog box...
         // already tried location.reload(); and window.location = <url to authentication form>;
      }
   }
   request.open("GET", "http://myServer", false, "domain\\username", "password");
   request.send(null);
}

我不希望在用户提供无效凭据时显示 NTLM 对话框。相反,应该执行身份验证表单中登录按钮的回发。换句话说,浏览器不应该发现我未经授权的请求。

有没有办法通过 JavaScript 来做到这一点?

有帮助吗?

解决方案

标记的评论是正确的;NTLM 身份验证提示由 401 响应代码触发,并且 NTLM 作为 WWW-Authenticate 标头中提供的第一个机制(参考: NTLM 身份验证协议).

我不确定我是否正确理解问题描述,但我认为您正在尝试包装 SharePoint 的 NTLM 身份验证,这意味着您无法控制服务器端身份验证协议,对吗?如果您无法操作服务器端以避免在凭据失败时发送 401 响应,那么您将无法避免此问题,因为它是(客户端)规范的一部分:

XMLHttpRequest 对象

如果UA支持HTTP身份验证[RFC2617],则应考虑源自此对象的请求,为保护空间的一部分,其中包括访问的URIS并发送授权标头并正确处理401个未经授权的请求。如果身份验证失败,UA 应提示用户输入凭据。

因此,规范实际上要求浏览器在 XMLHttpRequest 中收到任何 401 响应时相应地提示用户,就像用户直接访问 URL 一样。据我所知,真正避免这种情况的唯一方法是让您控制服务器端并避免 401 未经授权的响应,正如 Mark 提到的。

最后一个想法是,您可以使用代理(例如另一台网络服务器上的单独服务器端脚本)来解决此问题。然后,该脚本接受用户并传递参数并检查身份验证,以便用户的浏览器不是发出原始 HTTP 请求的浏览器,因此不会收到导致提示的 401 响应。如果您这样做,您可以从“代理”脚本中找出它是否失败,如果是,则再次提示用户直到成功。在成功的身份验证事件中,您可以像现在一样简单地获取 HTTP 请求,因为如果正确指定了凭据,一切都会正常进行。

其他提示

IIRC,当请求流中返回以下内容时,浏览器会弹出身份验证对话框:

  • 401 的 HTTP 状态
  • WWW-验证标头

我猜你需要抑制其中之一或两者。最简单的方法是使用一个登录方法,该方法将采用 Base64 用户名和密码(您使用的是 HTTPS,对吧?)并返回 200 以及有效/无效状态。密码经过验证后,您可以将其与 XHR 一起使用。

我能够让这个工作适用于除火狐之外的所有浏览器。请参阅下面我几年前的博客文章。我的帖子仅针对 IE,但通过一些小的代码更改,它应该可以在 Chrome 和 safari 中工作。

http://steve.thelineberrys.com/ntlm-login-with-anonymous-fallback-2/

编辑:

我的帖子的要点是将 JS xml 调用包装在 try catch 语句中。在 IE、Chrome 和 Safari 中,这将抑制 NTLM 对话框。它在 Firefox 中似乎没有按预期工作。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top