什么是 NTLM/身份验证/协商 Web 身份验证

Dav*_*len 0 c# ntlm httpwebrequest http-authentication http-negotiate

我了解基本和摘要身份验证。但是我已经搜索了很多,并且在 NTLM、身份验证和协商方面遇到了困难。

我认为,如果我错了,请纠正我,NTLM 和身份验证是同一协议的两个术语。

协商首先尝试 NTLM,然后回退到消化,然后回退到基本连接。

那是对的吗?如果是这样,哪里有一个很好的例子,说明如何在 C# 中连接仅用于 NTLM 和协商。

我有两个用例。首先是我需要拉下一个文件。所以发出一个请求,得到一个 XML 文件作为响应,读下来,完成。

第二个是查询 OData 成百上千个 Web 请求,每个请求都将提供 JSON(或 XML)作为响应。

pee*_*ngh 5

Microsoft Negotiate 是一个安全支持提供程序 (SSP),它充当安全支持提供程序接口 (SSPI) 和其他 SSP 之间的应用程序层。当应用程序调用 SSPI 登录网络时,它可以指定一个 SSP 来处理请求。如果应用程序指定了 Negotiate,Negotiate 会分析请求并根据客户配置的安全策略选择最佳 SSP 来处理请求。

https://docs.microsoft.com/en-us/windows/desktop/secauthn/microsoft-negotiate

正如文章中给出的那样,谈判不会回退到消化。在某种程度上,Negotiate 类似于 Kerberos,但具有 NTLM 的默认备份

目前,协商安全包在 Kerberos 和 NTLM 之间进行选择。Negotiate 选择 Kerberos,除非它不能被身份验证所涉及的系统之一使用,或者调用应用程序没有提供足够的信息来使用 Kerberos。

Windows 质询/响应 (NTLM) 是在包括运行 Windows 操作系统的系统和独立系统的网络上使用的身份验证协议。

Authenticate 只是一种内部方法,不知道为什么你会对它和协议感到困惑,内部结构很好看:https : //blogs.msdn.microsoft.com/dsnotes/2015/12/30/negotiate -vs-ntlm/

看待这个问题的方法是:

  1. 微软最初提出了一种在 Windows 服务器/机器上进行身份验证的方法,他们称之为NTLM,这使用了请求/响应(有时称为挑战)方法。
  2. 随后,他们提出了一个名为 Kerberos 的新协议并被采用。
  3. 为了确保现有的应用程序在旧的/新的情况下都能正常运行,我们有一种新的身份验证方法,称为 Negotiate,它尝试了 Kerberos,如果不可用,则使用 NTLM。

编辑 1:将这些身份验证机制应用于 Web 已在RFC 4559中正式化。

编辑 2: NTLM 验证一个连接,而不是一个请求,而其他身份验证机制通常验证一个请求。在第一个用例中,这应该不会有太大变化,但对于第二个用例,尝试 NTLM 同时保持一个连接是有意义的(通过使用 HTTP Keep-Alive,并且在第一个请求中只发送一次凭据)。可能存在性能差异。让我们随时了解您的结果。

取自Microsoft docs 的示例 WebRequest 代码,您可以将 Webrequest 替换为 HttpWebRequest。

            // Create a request for the URL.   
            WebRequest request = WebRequest.Create(  
              "http://www.contoso.com/default.html");  
            // If required by the server, set the credentials.  
            request.Credentials = CredentialCache.DefaultCredentials;  
            // Get the response.  
            WebResponse response = request.GetResponse();  
            // Display the status.  
            Console.WriteLine (((HttpWebResponse)response).StatusDescription);  
            // Get the stream containing content returned by the server.  
            Stream dataStream = response.GetResponseStream();  
            // Open the stream using a StreamReader for easy access.  
            StreamReader reader = new StreamReader(dataStream);  
            // Read the content.  
            string responseFromServer = reader.ReadToEnd();  
            // Display the content.  
            Console.WriteLine(responseFromServer);  
            // Clean up the streams and the response.  
            reader.Close();  
            response.Close();  
Run Code Online (Sandbox Code Playgroud)