С помощью HttpClient и Windows авторизации: пароль пользователя, вошедшего в систему бытового обслуживания



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



Мой потребитель-это приложение MVC. Мой сервис - это приложение Web Api. Оба работают на разных серверах в пределах одного домена. Оба настроены на использование Windows Auth.



Мой потребительский код:



private T GenericGet<T>(string p)
{
T result = default(T);

HttpClientHandler handler = new HttpClientHandler() { PreAuthenticate = true, UseDefaultCredentials = true };
using (HttpClient client = new HttpClient(handler))
{
client.BaseAddress = new Uri(serviceEndPoint);

HttpResponseMessage response = client.GetAsync(p).Result;
if (response.IsSuccessStatusCode)
result = response.Content.ReadAsAsync<T>().Result;
}

return result;
}


В моем сервисе я звоню User.Identity.Name, чтобы получить идентификатор вызывающего абонента, но он всегда возвращается как идентификатор пула приложений-потребителей, а не пользователя, вошедшего в систему. Потребитель Пул приложений работает как сетевая служба, сам сервер является доверенным для делегирования. Итак, как мне получить зарегистрированного пользователя? Служебный код:



    // GET: /Modules/5/Permissions/
[Authorize]
public ModulePermissionsDTO Get(int ModuleID)
{
Module module= moduleRepository.Find(ModuleID);
if (module== null)
throw new HttpResponseException(HttpStatusCode.NotFound);

// This just shows as the App Pool the MVC consumer is running as (Network Service).
IPrincipal loggedInUser = User;

// Do I need to do something with this instead?
string authHeader = HttpContext.Current.Request.Headers["Authorization"];

ModulePermissionsDTO dto = new ModulePermissionsDTO();
// Construct object here based on User...

return dto;
}


Согласно этому вопросу, Kerberos требуется, чтобы эта настройка работала, потому что HttpClient выполняется в отдельном потоке. Однако это сбивает меня с толку, потому что я думал, что запрос отправляет заголовок авторизации, и поэтому служба должна иметь возможность использовать это и получить маркер пользователя. В любом случае, я провел некоторые тесты с Kerberos чтобы проверить, что это правильно работает на моем домене, используя демонстрацию в "ситуации 5" здесь , и это работает, но мои два приложения все еще не могут правильно передать зарегистрированного пользователя.



Итак, что мне нужно сделать, чтобы это сработало? Нужен ли Kerberos или мне нужно что-то сделать в моей службе, чтобы распаковать заголовок авторизации и создать основной объект из маркера? Все советы ценил.

657   3  

3 ответов:

Ключ состоит в том, чтобы позволить вашему приложению MVC (потребителю) олицетворять вызывающего пользователя, а затем выдавать запросы HTTP синхронно (т. е. без порождения нового потока). Вам не нужно беспокоиться о деталях реализации низкого уровня, таких как NTLM vs Kerberos.

Потребитель

Настройте приложение MVC следующим образом:

  1. запустите диспетчер IIS
  2. выберите веб-приложение MVC
  3. двойной щелчок по кнопке "Аутентификация"
  4. включить 'ASP.NET олицетворение'
  5. Включить 'Аутентификацию Windows'
  6. отключить другие формы аутентификации (если, возможно, не дайджест, если вам это нужно)
  7. откройте веб.конфигурационный файл в корне вашего приложения MVC и убедитесь, что <authentication mode="Windows" />

Для выдачи HTTP-запроса я рекомендую вам использовать отличную библиотеку RestSharp. Пример:

var client = new RestClient("<your base url here>");
client.Authenticator = new NtlmAuthenticator();
var request = new RestRequest("Modules/5/Permissions", Method.GET);
var response = client.Execute<ModulePermissionsDTO>(request);

Обслуживание

Настройте свой Web API сервис Вот так:

  1. запустите диспетчер IIS
  2. выберите свой веб-API сервис
  3. дважды щелкните на "аутентификация"
  4. отключить 'ASP.NET олицетворение".
  5. Включить 'Аутентификацию Windows'
  6. Если аутентификация пользователей требуется только для подмножества методов веб-API, оставьте "анонимную аутентификацию" включенной.
  7. откройте веб.конфигурационный файл в корне службы Web API и убедитесь, что <authentication mode="Windows" />

Я вижу, что вы уже украсили свой метод атрибутом [Authorize], который должен вызвать вызов аутентификации (HTTP 401) при обращении к методу. Теперь вы должны иметь возможность получить доступ к идентификатору вашего конечного пользователя через свойство User.Identity вашего класса ApiController.

Ключевой проблемой двойного прыжка является делегирование учетных данных пользователя второму вызову. Я хочу немного подробнее рассказать об этом. C1 = браузер клиента, S1 = первый сервер, S2 = второй сервер.

Предположим, что наша полная система поддерживает аутентификацию окна. Когда пользователь обращается к S1 из браузера, его учетные данные окна по умолчанию передаются серверу S1 , но когда S1 делает вызов S2, по умолчанию он не передает учетные данные S2.

Разрешение:

  1. мы должны включить окно аутентификация / олицетворение на обеих машинах.
  2. нам нужно включить делегирование между серверами, чтобы S1 мог доверять S2 и передавать учетные данные S2.

Вы можете найти некоторые полезные сведения по ссылкам ниже : http://blogs.msdn.com/b/farukcelik/archive/2008/01/02/how-to-set-up-a-kerberos-authentication-scenario-with-sql-server-linked-servers.aspx

Https://sqlbadboy.wordpress.com/2013/10/11/the-kerberos-double-hop-problem/

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

var request = new RestRequest(Method.POST);

Если вы хотите использовать учетные данные приложений по умолчанию, которые должны иметь доступ на сервере размещенной службы

request.UseDefaultCredentials = true;

или пользователь ниже, чтобы передать учетные данные вручную

request.Credentials = new NetworkCredential("Username", "Password", "Domain");

Comments

    Ничего не найдено.