Как избежать множественных ошибок 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.