什么是 NTLM/Authenticate/Negotiate 网络认证

What is NTLM/Authenticate/Negotiate web authentication

我了解基本身份验证和摘要身份验证。但我已经搜索了很多,但我正在为 NTLM、身份验证和协商而苦苦挣扎。

我想,如果我错了请纠正我,NTLM 和 Authenticate 是同一协议的两个术语。

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

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

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

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

Microsoft Negotiate is a security support provider (SSP) that acts as an application layer between Security Support Provider Interface (SSPI) and the other SSPs. When an application calls into SSPI to log on to a network, it can specify an SSP to process the request. If the application specifies Negotiate, Negotiate analyzes the request and picks the best SSP to handle the request based on customer-configured security policy.

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

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

Currently, the Negotiate security package selects between Kerberos and NTLM. Negotiate selects Kerberos unless it cannot be used by one of the systems involved in the authentication or the calling application did not provide sufficient information to use Kerberos.

Windows Challenge/Response (NTLM) is the authentication protocol used on networks that include systems running the Windows operating system and on stand-alone systems.

Authenticate 只是一种内部方法,不确定您为什么会对它和协议感到困惑,在这里仔细看看内部结构:https://blogs.msdn.microsoft.com/dsnotes/2015/12/30/negotiate-vs-ntlm/

看这个的方法是:

  1. Microsoft 最初提出了一种在 Windows servers/machine 上进行身份验证的方法,他们称之为 NTLM,这使用了 request/response(有时称为挑战)方法。
  2. 随后他们提出了一个名为 Kerberos 的新协议并被采用。
  3. 为了确保现有应用程序在 old/new 下都能正常运行,我们有一种名为协商的新身份验证方法,它尝试了 Kerberos,如果它不可用,则使用 NTLM。

编辑 1 :RFC 4559.

中正式将这些身份验证机制应用于 Web

编辑 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();