Вопрос по asp.net-web-api, asp.net-mvc-4, windows-authentication, wcf-web-api, iis-7.5 – Невозможно пройти аутентификацию в ASP.NET Web Api с помощью HttpClient

35

У меня есть служба веб-API ASP.NET, которая работает на веб-сервере с включенной аутентификацией Windows.

У меня есть клиентский сайт, построенный на MVC4, который работает на другом сайте на том же веб-сервере, который использует HttpClient для извлечения данных из службы. Этот клиентский сайт работает с включенной идентификацией личности, а также использует проверку подлинности Windows.

Веб-сервер - Windows Server 2008 R2 с IIS 7.5.

Проблема, с которой я столкнулся, заключается в том, чтобы заставить HttpClient передать текущего пользователя Windows как часть процесса аутентификации. Я настроил HttpClient следующим образом:

<code>var clientHandler = new HttpClientHandler();
clientHandler.UseDefaultCredentials = true;
clientHandler.PreAuthenticate = true;
clientHandler.ClientCertificateOptions = ClientCertificateOption.Automatic;
var httpClient = new HttpClient(clientHandler);
</code>

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

Это не происходит Фактически, клиент, похоже, вообще не аутентифицируется.

Служба настроена на использование проверки подлинности Windows, и это, кажется, работает отлично. Я могу пойти вHttp: // сервер / API / грузоотправителей в моем веб-браузере и запрос на проверку подлинности Windows, после ввода я получаю запрошенные данные.

В журналах IIS я вижу, что запросы API принимаются без аутентификации и получают ответ на вызов 401.

Документация по этому вопросу, кажется, скудна.

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

Благодарю вас, Craig

Ваш Ответ

4   ответа
0

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

Первый переход - это веб-сервер, в котором нет проблем с олицетворением аутентификации Windows. Но при использовании HttpClient или WebClient для проверки подлинности на другом сервере веб-сервер должен работать с учетной записью, которая имеет разрешение на необходимое делегирование.

Смотрите следующие подробности:
http://blogs.technet.com/b/askds/archive/2008/06/13/understanding-kerberos-double-hop.aspx

Исправьте с помощью «setspn» команда:
http://www.phishthis.com/2009/10/24/how-to-configure-ad-sql-and-iis-for-two-hop-kerberos-authentication-2/ (Для выполнения этих операций вам потребуются достаточные права доступа.)

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

9

проведенному @tpeczek, я разработал следующее решение: вместо использования HttpClient (который создает потоки и отправляет запросы асинхронно), я использовал класс WebClient, который выдает запросы в том же потоке. Это позволяет мне передавать идентификатор пользователя в WebAPI из другого приложения ASP.NET.

Очевидным недостатком является то, что это не будет работать асинхронно.

var wi = (WindowsIdentity)HttpContext.User.Identity;

var wic = wi.Impersonate();
try
{
    var data = JsonConvert.SerializeObject(new
    {
        Property1 = 1,
        Property2 = "blah"
    });

    using (var client = new WebClient { UseDefaultCredentials = true })
    {
        client.Headers.Add(HttpRequestHeader.ContentType, "application/json; charset=utf-8");
        client.UploadData("http://url/api/controller", "POST", Encoding.UTF8.GetBytes(data));
    }
}
catch (Exception exc)
{
    // handle exception
}
finally
{
    wic.Undo();
}

Note: Требуется пакет NuGet: Newtonsoft.Json, который является тем же сериализатором JSON, который использует WebAPI.

Вот это да. WindowsImpersonationContext. Вы спасли день и мое здравомыслие. Спасибо.
Это не сработало для меня. Я все еще получаю 401 Несанкционированный.
Вы пытались использовать асинхронные аналоги, такие как UploadDataAsync :-)
Спасибо, это то, что мне было нужно.
0

используйте следующую конфигурацию в файле Web.config:

<authentication mode="Windows" />
<identity impersonate="true" />

При такой конфигурации ASP.NET всегда олицетворяет аутентифицированного пользователя, и весь доступ к ресурсам выполняется с использованием контекста безопасности аутентифицированного пользователя.

32

которую мне удалось достать), и это то, что можно найти в методе SendAsync:

// BeginGetResponse/BeginGetRequestStream have a lot of setup work to do before becoming async
// (proxy, dns, connection pooling, etc).  Run these on a separate thread.
// Do not provide a cancellation token; if this helper task could be canceled before starting then 
// nobody would complete the tcs.
Task.Factory.StartNew(startRequest, state);

Теперь, если вы проверите в своем коде значение SecurityContext.IsWindowsIdentityFlowSuppressed (), вы, скорее всего, получите значение true. В результате метод StartRequest выполняется в новом потоке с учетными данными процесса asp.net (не учетными данными пользователя, выдавшего себя за другого).

Есть два возможных выхода из этого. Если у вас есть доступ к вашему серверу aspnet_config.config, вы должны установить следующие настройки (установка в web.config, похоже, не имеет никакого эффекта):

<legacyImpersonationPolicy enabled="false"/>
<alwaysFlowImpersonationPolicy enabled="true"/>

Если вы не можете изменить aspnet_config.config, вам придется создать собственный HttpClientHandler для поддержки этого сценария.

UPDATE REGARDING THE USAGE OF FQDN

Проблема, с которой вы столкнулись, - это функция в Windows, предназначенная для защиты от «атак отражения». Чтобы обойти это, вам нужно добавить в белый список домен, к которому вы пытаетесь получить доступ на компьютере, который пытается получить доступ к серверу. Выполните следующие шаги:

Go to Start --> Run --> regedit Locate HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0 registry key. Right-click on it, choose New and then Multi-String Value. Type BackConnectionHostNames (ENTER). Right-click just created value and choose Modify. Put the host name(s) for the site(s) that are on the local computer in the value box and click OK (each host name/FQDN needs to be on it's own line, no wildcards, the name must be exact match). Save everything and restart the machine

Вы можете прочитать полную статью базы знаний о проблемеВот.

@CraigAnderson Можете ли вы проверить значения System.Security.Principal.WindowsIdentity.GetCurrent () и SecurityContext.IsWindowsIdentityFlowSuppressed () непосредственно перед выполнением запроса с помощью HttpClient? Если речь идет о потоке запросов, это правильно. Если для параметра PreAuthenticate задано значение true, HttpClient отправляет заголовок авторизации с первоначальным запросом. Если ответом является 401, он не предпринимает никаких дальнейших попыток аутентификации, поскольку учетные данные, которые могут быть отправлены, уже были отклонены.
Хорошо подмечено!..
Я пошел дальше и установил эти значения без изменений в поведении. Странно то, что я вижу, как клиент подключается к серверу и получает ответ 401. Кажется, что HttpClient НЕ посылает никакой аутентификационной информации, а просто получает 401 и завершает работу. Есть дополнительные мысли? Craig Anderson
Я столкнулся с той же проблемой и предложением обновить & quot; legacyImpersonationPolicy & quot; и & quot; AlwaysFlowImpersonationPolicy & quot; теги работают, но я бы хотел этого избежать, поскольку это изменение всей машины. Эта ссылка указывает, что возможно иметь файл aspnet.config для пула приложений, но я не смог заставить его работать. Кому-нибудь повезло с этим?weblogs.asp.net/owscott/archive/2011/12/01/…
Кроме того, я изменил удостоверение пула приложений, в котором работает клиент, на учетную запись Windows, которая имеет доступ к службе. Это не приводит к изменениям. Я заблудился на этом? Craig Anderson

Похожие вопросы