有没有办法检查浏览器中是否有Windows身份验证(Negotiate,Kerberos,NTLM ...)(使用JavaScript或其他方法),如果没有浏览器提示输入用户名和密码?
背景
我们正在开发Angular2 SPA企业应用程序,并希望SSO具有Windows身份验证(如果可用)(用户从Domain join计算机访问该应用程序)并优雅地故障转移到基于表单的身份验证(如果它不可用)(从互联网或非域名加入计算机)。
设置
在服务器端(即REST方法)拥有受Windows身份验证保护的资源。当您使用JavaScript调用此REST方法时,将发生以下两种情况之一:
问题
显示登录提示是不受欢迎的,我们希望优雅地回退到基于表单的登录。
有些solutions建议从响应中删除WWW-Authenticate标头,但这会阻止Windows身份验证工作,因为此步骤是broser-server协商身份验证协议的一部分。如果删除,浏览器将永远不会发送NTLM或Kerberos令牌。
我们控制前端和后端,因此可以修改任何一个以使其工作。此外,没有CORS,一切都是来自单个域的服务器。
任何可以检测客户端是否可以使用Windows身份验证的方法对我们来说都足够了。到目前为止我发现的是this,但它仅适用于IE并且需要启用ActiveX。 This问题有些相关,但它也没有解决方案而且已经很老了。
答案 0 :(得分:1)
我们在Web Worker中使用XmlHttpRequest。 这样就可以执行Kerberos身份验证,如果失败则不会触发登录窗口。
IE11支持Web Workers,因此您应该善于使用它。
这涉及证明单个API端点,您可以尝试通过Kerberos进行身份验证,例如'yourhost.tld / krb5LoginUrl'
您的Webworker(提供为例如task.js):
self.addEventListener('message', function(e) {
var oReq = new XMLHttpRequest();
oReq.addEventListener("load", reqListener);
oReq.open("GET", e.data);
oReq.send(null);
function reqListener () {
self.postMessage(this.status);
}, false);
在主应用程序代码中注册worker: const worker = new Worker('task.js');
worker.postMessage(/krb5LoginUrl); // Sends the url to our worker and triggers xmlHttpRequest.
worker.addEventListener('message', function (e) {
if (e.data == 200) {
console.log("Krb5 login successful");
} else {
console.log("Krb5 login failed");
}
}, false);
}