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

时间:2019-03-26 00:33:04

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

我了解基本身份验证和摘要身份验证。但是我已经搜索了很多东西,并且在NTLM,身份验证和协商方面苦苦挣扎。

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

并且协商首先尝试NTLM,然后回退至摘要,然后回退至基本连接。

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

我有两个用例。首先是我需要下拉单个文件。因此,发出一个请求,获取一个XML文件作为响应,然后将其读取并完成。

第二种方法是查询OData,以便数百至数千个Web请求,每个Web请求都将提供JSON(或XML)作为响应。

1 个答案:

答案 0 :(得分:2)

  

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

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

如文章中所述,谈判不会退缩。在某种程度上,协商类似于Kerberos,但具有NTLM的默认备份

  

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

     

Windows质询/响应(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: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();