Как избежать множественных ошибок 401 при использовании проверки подлинности Windows на HTTP.sys

У меня есть веб-API, использующий ядро ​​.NET 2.2 и HTTP.Sys. Я установил аутентификацию Windows и вижу запрос 401 WWW-Negotiate, за которым следует 200, когда пользователь авторизован.

Я выполнил один и тот же запрос несколько раз, но вижу, что проблема возникает при каждом запросе, замедляя работу системы и влияя на производительность. Мой образец клиента:

var httpHandler = new HttpClientHandler
{
    UseDefaultCredentials = true,
    Proxy = new WebProxy
    {
        Address = new Uri("http://HOSTNAME:8888"),
    }
};

using (var client = new HttpClient(httpHandler))
{

client.BaseAddress = new Uri("http://HOSTNAME:5000/");
for (int i = 0; i < 10; i++)
{
    try
    {
        HttpResponseMessage response = client.GetAsync("api/user").Result;
        response.EnsureSuccessStatusCode();
        string result = response.Content.ReadAsStringAsync().Result;
        Console.WriteLine("Result: " + result);
    }
    catch (System.Exception ex)
    {
        Console.WriteLine(ex);
    }
}

Я читал, что для IIS, кажется, вы можете использовать authPersistNonNTLM=true здесь, но я не мог одобрить аналогичную настройку для чистого HTTP.sys. Есть идеи?

Спасибо,

1 ответ

Я не вижу подобной опции в HttpSysOptions class (параметры, которые вы передаете в HTTP.sys).

Что может помочь, так это не выбрасывать HttpClient (не используйте using в теме). HttpClientявляется потокобезопасным и предназначен для повторного использования. Фактически, вы должны держатьstaticссылку на него и использовать повторно. Существует продолжительная дискуссия о том, почему здесь, но вкратце: если вы этого не сделаете, он не будет повторно использовать соединения.

Это может иметь какое-то отношение к тому, почему вы это видите. Но если это не решает проблему, отслеживайте трафик и посмотрите, отправляются ли данные аутентификации клиентом при первом запросе. Они должны быть, поскольку вы устанавливаетеUseDefaultCredentialsа если нет, то это ваша проблема.

Обновление: вы также можете попробовать установить PreAuthenticate собственность на вашем HttpClientHandler:

var httpHandler = new HttpClientHandler
{
    UseDefaultCredentials = true,
    PreAuthenticate = true,
    Proxy = new WebProxy
    {
        Address = new Uri("http://HOSTNAME:8888"),
    }
};

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

Другие вопросы по тегам