jQuery Javascript/Ajax NTLM 身份验证
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18527749/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Javascript/Ajax NTLM Authentication
提问by TryCatch
I am developing an HTML5 mobile app, which communicates with WebServices
. WebServices use NTLM authentication protocol. I am having difficulties to handle the handshake via JavaScript. NTLM sends the 401 unauthorized
as response to my POST, which I have not found any way to respond to.
我正在开发一个 HTML5 移动应用程序,它与WebServices
. Web 服务使用 NTLM 身份验证协议。我很难通过 JavaScript 处理握手。NTLM 将401 unauthorized
作为响应发送到我的 POST,我还没有找到任何响应方式。
Is NTLM authentication possible with JavaScript? Should I build a proxy web service with e.g. basic authentication in-between?
是否可以使用 JavaScript 进行 NTLM 身份验证?我应该构建一个代理 Web 服务,例如中间有基本身份验证吗?
my jQuery call is something like...
我的 jQuery 调用类似于...
$.ajax({
type: "POST",
url: URL,
contentType: "text/xml",
dataType: "xml",
data: soapRequest,
username: 'username',
password: 'password',
xhrFields: {
withCredentials: true
},
success: processSuccess,
error: processError
});
回答by QA Collective
You don't have to respond to the NTLM (Integrated Windows Authentication) challenge, your browser should do it for you, if properly configured. A number of additional complications are likely too.
您不必响应 NTLM(集成 Windows 身份验证)质询,如果配置正确,您的浏览器应该会为您执行此操作。也可能出现许多其他并发症。
Step 1 - Browser
第 1 步 - 浏览器
Check that the browser can access and send your credentials with an NTLM web application or by hitting the software you're developing directly first.
检查浏览器是否可以使用 NTLM Web 应用程序访问和发送您的凭据,或者首先直接点击您正在开发的软件。
Step 2 - JavaScript withCredentials attribute
第 2 步 - JavaScript withCredentials 属性
The 401 Unauthorizederror received and the symptoms described are exactly the same when I had failed to set the 'withCredentials' attribute to 'true'. I'm not familiar with jQuery, but make sure your attempt at setting that attribute is succeeding.
当我未能将“withCredentials”属性设置为“true”时,收到的401 Unauthorized错误和描述的症状完全相同。我不熟悉 jQuery,但请确保您设置该属性的尝试成功。
This example works for me:
这个例子对我有用:
var xhttp = new XMLHttpRequest();
xhttp.open("GET", "https://localhost:44377/SomeService", true);
xhttp.withCredentials = true;
xhttp.send();
xhttp.onreadystatechange = function(){
if (xhttp.readyState === XMLHttpRequest.DONE) {
if (xhttp.status === 200)
doSomething(xhttp.responseText);
else
console.log('There was a problem with the request.');
}
};
Step 3 - Server side enable CORS (Optional)
第 3 步 - 服务器端启用 CORS(可选)
I suspect a major reason people end up at this question is that they are developing one component on their workstation with another component hosted elsewhere. This causes Cross-Origin Resource Sharing (CORS)issues. There are two solutions:
我怀疑人们最终回答这个问题的一个主要原因是他们正在他们的工作站上开发一个组件,而另一个组件则托管在其他地方。这会导致跨域资源共享 (CORS)问题。有两种解决方案:
- Disable CORS in your browser - good for development when ultimately your work will be deployed on the same origin as the resource your code is accessing.
- Enable CORS on your server - there is ample reading on the broader internet, but this basically involves sending headers enabling CORS.
- 在浏览器中禁用 CORS - 当最终您的工作将部署在与您的代码正在访问的资源相同的来源上时,这对开发很有好处。
- 在您的服务器上启用 CORS - 在更广泛的互联网上有足够的阅读,但这主要涉及发送启用 CORS 的标头。
In short, to enable CORS with credentialsyou must:
简而言之,要使用凭据启用 CORS ,您必须:
- Send a 'Access-Control-Allow-Origin' header that matches the origin of the served page ... this cannot be '*'
- Send a 'Access-Control-Allow-Credentials' with value 'true'
- 发送与服务页面的来源匹配的“Access-Control-Allow-Origin”标头......这不能是“*”
- 发送值为“true”的“Access-Control-Allow-Credentials”
Here is my working .NET code sample in my global.asax file. I think its pretty easy to see what's going on and translate to other languages if needed.
这是我在 global.asax 文件中工作的 .NET 代码示例。我认为很容易看到正在发生的事情并在需要时翻译成其他语言。
void Application_BeginRequest(object sender, EventArgs e)
{
if (Request.HttpMethod == "OPTIONS")
{
Response.AddHeader("Access-Control-Allow-Methods", "GET, POST");
Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept");
Response.AddHeader("Access-Control-Max-Age", "1728000");
Response.End();
}
else
{
Response.AddHeader("Access-Control-Allow-Credentials", "true");
if (Request.Headers["Origin"] != null)
Response.AddHeader("Access-Control-Allow-Origin" , Request.Headers["Origin"]);
else
Response.AddHeader("Access-Control-Allow-Origin" , "*"); // Last ditch attempt!
}
}
回答by Doct0rZ
As far as I have seen, no one has implemented Windows Integrated/NTLM auth with AJAX, although it should be possible (I'm considering doing it for a current project to combine form authentication with the WindowsTokenRoleProvider)
据我所知,没有人使用 AJAX 实现 Windows Integrated/NTLM 身份验证,尽管它应该是可能的(我正在考虑为当前项目将表单身份验证与 WindowsTokenRoleProvider 结合起来)
The basic workflow shouldbreakdown like this (based on articles hereand here):
- do a GET request with a base64-encoded type-1 NTLM message in the "Authorization" header
- take the base64-encoded type-2 NTLM message out of the "WWW-Authenticate" header in the 401 response.
- perform the NTLM operation on the noonce recieved in the previous step (sorry I don't have a code example yet)
- perform a final GET with a base64-encoded type-3 NTLM message in the "Authorization" header. This should return a 200.
- 在“授权”标头中使用 base64 编码的 type-1 NTLM 消息执行 GET 请求
- 从 401 响应中的“WWW-Authenticate”标头中取出 base64 编码的 type-2 NTLM 消息。
- 对上一步收到的 noonce 执行 NTLM 操作(抱歉我还没有代码示例)
- 在“授权”标头中使用 base64 编码的 type-3 NTLM 消息执行最终 GET。这应该返回 200。
NTLM auth over HTTP is more of a CHAP implementation using HTTP than it is an authorized HTTP request.
HTTP 上的 NTLM 身份验证更像是使用 HTTP 的 CHAP 实现,而不是授权的 HTTP 请求。
I'll update you if I actually get around to implementing this. Sorry I couldn't be of more help.
如果我真的开始实施这个,我会更新你。对不起,我帮不上忙了。
回答by Kinetic
The problem is that you can't get the currently logged in domain/user via javascript (or if you can I've never found a solution).
问题是您无法通过 javascript 获取当前登录的域/用户(或者如果可以的话,我从未找到解决方案)。
If you already know the domain, username and password you could use something like https://github.com/erlandranvinge/ntlm.js/tree/master
如果您已经知道域、用户名和密码,您可以使用类似https://github.com/erlandranvinge/ntlm.js/tree/master 的内容
However I think going down this method for single sign on is going to be frustrating in the long run.
但是,我认为从长远来看,采用这种方法进行单点登录会令人沮丧。
We ended up doing NTLM authentication in a hidden iframe and accessing the iframe via javascript.
我们最终在隐藏的 iframe 中进行 NTLM 身份验证并通过 javascript 访问 iframe。
回答by MinimalMaximizer
Yeah NTLM isn't very fun. But you might want to try this, https://github.com/tcr/node-ntlm/blob/master/README.md
是的,NTLM 不是很有趣。但你可能想试试这个, https://github.com/tcr/node-ntlm/blob/master/README.md