Как System.Net.Http.HttpClient выбирает тип аутентификации? - PullRequest
6 голосов
/ 17 мая 2019

Допустим, я обновил 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 ...

Из заголовков ответов я вижу, что у меня есть три различных варианта аутентификации на сервере (Negotiate, NTLM, Basic).Затем я обновляю свой код так:

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 в ответ.Все в порядке.

Если я проверяю запрос с помощью fiddler, я вижу, что HttpClient решил использовать «Согласование» в качестве метода аутентификации.

Теперь мой вопрос: как HttpClient решает, какой тип аутентификации применять?Имеет ли он приоритет для некоторых типов аутентификации над другими?

В документах по NetworkCredential указано, что:

Класс NetworkCredential является базовым классом, которыйпредоставляет учетные данные в схемах аутентификации на основе паролей, таких как basic, digest, NTLM и Kerberos.

... поэтому я знаю, что предоставленные мной учетные данные могли быть применены для всех трех типов аутентификации, но яне удалось выяснить, как / почему он выбирает определенный тип аутентификации вместо другого.

Любое понимание этого очень приветствуется, заранее спасибо!

1 Ответ

0 голосов
/ 17 мая 2019

Вы можете использовать метод 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-аутентификация - заголовок WWW-Authenticate - несколько областей

...