У меня есть веб-приложение (размещенное в IIS), которое взаимодействует со службой Windows. Служба Windows использует веб-API ASP.Net MVC (самодостаточно размещенный), поэтому с ним можно обмениваться данными через http с помощью JSON. Веб-приложение сконфигурировано для выполнения олицетворения, идея состоит в том, что пользователь, который отправляет запрос веб-приложению, должен быть пользователем, которого веб-приложение использует для выполнения запроса к службе. Структура выглядит так:
(Пользователь, выделенный красным цветом, является пользователем, на который ссылаются в примерах ниже.)
Веб-приложение отправляет запросы в службу Windows, используя HttpClient
:
var httpClient = new HttpClient(new HttpClientHandler()
{
UseDefaultCredentials = true
});
httpClient.GetStringAsync("http://localhost/some/endpoint/");
Это делает запрос к службе Windows, но не передает учетные данные правильно (служба сообщает пользователю как IIS APPPOOL\ASP.NET 4.0
). Это не то, что я хочу, чтобы произошло .
Если я изменю приведенный выше код, чтобы использовать WebClient
вместо него, учетные данные пользователя передаются правильно:
WebClient c = new WebClient
{
UseDefaultCredentials = true
};
c.DownloadStringAsync(new Uri("http://localhost/some/endpoint/"));
С помощью приведенного выше кода служба сообщает о пользователе как о пользователе, который сделал запрос к веб-приложению.
Что я делаю не так с HttpClient
реализацией, из-за которой он не проходит учетные данные правильно (или это ошибка с HttpClient
)?
Причина, по которой я хочу использовать это, HttpClient
заключается в том, что у него есть асинхронный API, который хорошо работает с Task
s, тогда как WebClient
асинхронный API s должен обрабатываться с событиями.
источник
DownloadStringTaskAsync
.Net 4.5, который также можно использовать с async / awaitHttpClient
не имеетSetCredentials()
метода. Можете ли вы указать мне, что вы имеете в виду?new HttpClient(new HttpClientHandler() { AllowAutoRedirect = true, UseDefaultCredentials = true }
на веб-сервере, к которому обращается пользователь, прошедший проверку подлинности Windows, и после этого веб-сайт действительно прошел проверку подлинности для другого удаленного ресурса (не прошел проверку подлинности без установленного флага).Ответы:
У меня тоже была такая же проблема. Я разработал синхронное решение благодаря исследованию, проведенному @tpeczek в следующей статье SO: Невозможно пройти аутентификацию в ASP.NET Web Api service с помощью HttpClient
Мое решение использует
WebClient
, который, как вы правильно заметили, передает учетные данные без проблем. ПричинаHttpClient
не работает, потому что безопасность Windows отключает возможность создавать новые потоки под олицетворенной учетной записью (см. Статью SO выше).HttpClient
Создает новые потоки через фабрику задач, вызывая ошибку.WebClient
с другой стороны, синхронно работает в том же потоке, минуя правило и пересылая его учетные данные.Хотя код работает, недостатком является то, что он не будет работать асинхронно.
Примечание: Требуется пакет NuGet: Newtonsoft.Json, который является тем же сериализатором JSON, который использует WebAPI.
источник
Вы можете настроить
HttpClient
автоматическую передачу учетных данных следующим образом:источник
То, что вы пытаетесь сделать, это заставить NTLM переслать удостоверение на следующий сервер, чего он не может сделать - он может выполнять только олицетворение, которое дает вам доступ только к локальным ресурсам. Это не позволит вам пересечь границу машины. Аутентификация Kerberos поддерживает делегирование (что вам нужно) с помощью билетов, и билет можно пересылать, когда все серверы и приложения в цепочке правильно настроены и Kerberos правильно настроен в домене. Короче говоря, вам нужно переключиться с использования NTLM на Kerberos.
Дополнительные сведения о доступных для вас вариантах аутентификации Windows и о том, как они работают, можно найти по адресу: http://msdn.microsoft.com/en-us/library/ff647076.aspx.
источник
WebClient
? Это то, чего я не понимаю - если это невозможно, то почему это происходит ?WebClient
может передавать учетные данные NTLM, ноHttpClient
не может. Я могу добиться этого, используя только олицетворение ASP.Net и не используя Kerberos или для хранения имен пользователей и паролей. Это, однако, работает только сWebClient
.Хорошо, так что спасибо всем авторам выше. Я использую .NET 4.6, и у нас тоже была такая же проблема. Я потратил время на отладку
System.Net.Http
, в частностиHttpClientHandler
, и обнаружил следующее:Итак, после оценки того, что,
ExecutionContext.IsFlowSuppressed()
возможно, виновник, я обернул наш код подражания следующим образом:Код внутри
SafeCaptureIdenity
(не моя орфографическая ошибка),WindowsIdentity.Current()
который захватывает нашу личность. Это поднято, потому что мы теперь подавляем поток. Из-за использования / утилизации это сбрасывается после вызова.Кажется, теперь это работает для нас, фу!
источник
using (System.Threading.ExecutionContext.SuppressFlow())
и проблема была решена для меня!В .NET Ядра, мне удалось получить
System.Net.Http.HttpClient
сUseDefaultCredentials = true
проходить через учетные данные Windows , прошедшему проверку подлинности пользователя на задней торцевой службы с помощьюWindowsIdentity.RunImpersonated
.источник
Это сработало для меня после того, как я настроил пользователя с доступом в интернет в службе Windows.
В моем коде:
источник
Итак, я взял код Джошуна и сделал его общим. Я не уверен, должен ли я реализовать шаблон синглтона в классе SynchronousPost. Может быть, кто-то более знающий может помочь.
Реализация
// Я предполагаю, что у вас есть свой конкретный тип. В моем случае я использую код сначала с классом под названием FileCategoryОбщий класс здесь. Вы можете пройти любой тип
Мой Api класс выглядит так, если вам интересно
Я использую ninject и репо с единицей работы. В любом случае, общий класс выше действительно помогает.
источник