HttpClient, вызывающий API, не проходит аутентификацию cookie

Попытка вызвать API из контроллера с помощью HttpClient, и API не распознает пользователя как аутентифицированного и вошедшего в систему. При вызове API из JS у меня нет проблем. Я заметил, что HttpClient отправлял только через HTTP 1.1, поэтому я обновил настройки до версии 2.0 с флагом DOTNET_SYSTEM_NET_HTTP_USESOCKETSHTTPHANDLER, но это не имело значения. Я пробовал все комбинации свойств HttpClientHandler, включая UseCookies, и запрос никогда не аутентифицируется.

        using (var handler = new HttpClientHandler {UseDefaultCredentials = true})
        {
            using (var httpClient = new HttpClient(handler))
            {
                var response = httpClient.GetStringAsync(new Uri($"https://localhost:64366/api/")).Result;
            }
        }

В будущем перейдет на аутентификацию на основе токенов, но сейчас хотелось бы понять, почему существует разница между вызовом API из C# и JS. Это все HTTPS на локальном хосте с использованием asp net core 2.2.


person InContext    schedule 27.01.2019    source источник
comment
Вы как-то добавили файл cookie в запрос на С#? Браузеры автоматически прикрепляют файлы cookie к запросам, так что это главное отличие.   -  person juunas    schedule 27.01.2019
comment
спасибо, я думал UseDefaultCredentials = true сделал это для меня?   -  person InContext    schedule 27.01.2019
comment
UseDefaultCredentials всегда true по умолчанию, и это только для использования учетных данных пользователя, запускающего приложение, которое не имеет ничего общего с самим веб-приложением.   -  person Camilo Terevinto    schedule 27.01.2019
comment
Тем не менее, вам нужно взять учетные данные текущего пользователя и передать их, в зависимости от того, как API аутентифицирует   -  person Camilo Terevinto    schedule 27.01.2019


Ответы (1)


Разница между JS и C# заключается в том, что браузеры автоматически прикрепляют файлы cookie к запросам, и вы должны прикреплять файлы cookie вручную в C#, как упоминалось juunas.

Чтобы получить и использовать файл cookie аутентификации, вы можете использовать следующий шаблон

CookieContainer cookies = new CookieContainer(); //this container saves cookies from responses and send them in requests
var handler = new HttpClientHandler
{
    CookieContainer = cookies
};

var client = new HttpClient(handler);

string authUrl = ""; //your auth url
string anyUrl = ""; //any url that requires you to be authenticated

var authContent = new FormUrlEncodedContent(
    new List<KeyValuePair<string, string>> {
        new KeyValuePair<string, string>("login", "log_in"),
        new KeyValuePair<string, string>("password", "pass_word")
        }
    );

//cookies will be set on this request
HttpResponseMessage auth = await client.PostAsync(authUrl, authContent);
auth.EnsureSuccessStatusCode(); //retrieving result is not required but you will know if something goes wrong on authentication

//and here retrieved cookies will be used
string result = await client.GetStringAsync(anyUrl);
person Alexander    schedule 27.01.2019
comment
спасибо - дал мне направление записи. Мне пришлось заполнить CookieContainer из файлов cookie запроса, и это сработало: foreach (var cookie в HttpContext.Request.Cookies) { cookies.Add (new Cookie (cookie.Key, cookie.Value, /, localhost)); } var clientHandler = новый HttpClientHandler { CookieContainer = cookies }; используя (var httpClient = новый HttpClient (clientHandler)) {} - person InContext; 29.01.2019