【问题标题】:What is NTLM/Authenticate/Negotiate web authentication什么是 NTLM/身份验证/协商 Web 身份验证
【发布时间】:2019-03-26 00:33:03
【问题描述】:

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

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

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

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

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

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

【问题讨论】:

  • 我不知道您所说的“身份验证”协议是什么意思,但协商是 Kerberos 身份验证(如果支持),如果不支持则回退到 NTLM。这是 HTTP 身份验证方案的官方 IANA list 和 Microsoft docs
  • 也许你应该改写你的问题以获得积极的投票。
  • @EugèneAdell 我很高兴改写这个问题 - 我应该改写什么?
  • 我会为您的每次尝试提供几行 c# 代码(我想您可以在任何地方轻松找到),并更加关注每种方法可能对每个用例产生的性能影响.只是发表我的意见,我不能代表 SO 社区(这通常令人失望)
  • @EugèneAdell 不幸的是,由于我只是在学习 NTLM 是什么并且不知道如何调用它,因此无法选择提供代码。

标签: c# httpwebrequest ntlm http-authentication http-negotiate


【解决方案1】:

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

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

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

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

Windows Challenge/Response (NTLM) 是使用的身份验证协议 在包含运行 Windows 操作系统的系统的网络上 在独立系统上。

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

看这个的方法是:

  1. Microsoft 最初提出了一种在 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();  

【讨论】:

  • 感谢您改进您的回答。 +1
  • 您能否添加一个指向示例代码的链接,以显示为 HttpWebRequest 调用它的正确方法?然后我很高兴选择这个作为答案。
  • 谢谢 - 我没有想到仅设置凭据就足以实现这一点。
猜你喜欢
  • 1970-01-01
  • 2015-01-10
  • 2014-08-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多