System.Net.Http.HttpClient如何选择身份验证类型?

时间:2019-05-17 07:59:06

标签: c# .net .net-core dotnet-httpclient

比方说,我新建了HttpClient并向这样的受保护端点发送了一个请求:

var httpClient = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "url");
var response = await httpClient.SendAsync(request);

然后我收到带有以下标头的响应:

HTTP/1.1 401 Unauthorized
Content-Type: text/html
WWW-Authenticate: Negotiate
WWW-Authenticate: NTLM
WWW-Authenticate: Basic
Date ...

从响应标头中,我看到我有三个用于与服务器进行身份验证的选项(协商,NTLM,基本)。然后,我将代码更新为:

var httpClientHandler = new HttpClientHandler
{
    Credentials = new NetworkCredential
    {
        UserName = "username",
        Password = "password"
    }
};
var httpClient = new HttpClient(httpClientHandler);
var request = new HttpRequestMessage(HttpMethod.Get, "url");
var response = await httpClient.SendAsync(request);

我再次执行我的程序,这次我得到200 OK的回报。很好。

如果我用提琴手检查请求,我会发现HttpClient决定使用“协商”作为身份验证方法。

现在,我的问题是:HttpClient如何决定要应用哪种身份验证类型?某些身份验证类型是否优先于其他身份验证类型?

NetworkCredential上的文档指出:

  

NetworkCredential类是提供凭据的基类   在基于密码的身份验证方案中,例如基本,摘要,NTLM,   和Kerberos。

...,所以我知道我提供的凭据可能已应用于所有三种身份验证类型,但是我无法弄清楚它为什么/为什么选择一种特定的身份验证类型而不是另一种。

对此表示感谢,感谢您!

1 个答案:

答案 0 :(得分:0)

您可以使用 GetCredential 方法,它将为您提供带有身份验证类型的凭据。有点奇怪,但是有效:

var httpClientHandler = new HttpClientHandler
{
    Credentials = new NetworkCredential
    {
        UserName = "username",
        Password = "password"       
    }.GetCredential("*", 80, "Basic") // Substitute * and 80 with url and port if possible
};
var httpClient = new HttpClient(httpClientHandler);
var request = new HttpRequestMessage(HttpMethod.Get, "url");
var response = await httpClient.SendAsync(request);

澄清评论后

当您具有多种身份验证类型时,客户端必须使用可用的最强方法(但这有时很难说)。

来源: HTTP Authentication - WWW-Authenticate header - multiple realms