CredentialsCache.DefaultCredentials в рамках задачи / потока

Я надеюсь, что вы можете мне помочь.

Я делаю некоторые веб-запросы в моем приложении C# 4.0, которые требуют аутентификации. Я просто использую CredentialsCache.DefaultCredentials, Это прекрасно работает, пока я не запускаю функциональность в другом потоке / задаче через Task<T>.Factory.StartNew(...), Я тогда получаю 401 ошибки. Я предполагаю, что учетные данные не передаются дочерним потокам?

Как я могу пройти через учетные данные для любых дочерних задач / потоков?

2 ответа

Я предполагаю, что вы используете олицетворение и проблема в том, что учетные данные не передаются в задачу. Стоит проверить этот момент, чтобы сохранить погоню за диким гусем, выкинув значение Windows.Identity.GetCurrent().Name как в исходном коде, так и в теле задачи и убедитесь, что это то, что вы ожидаете.

Таким образом, с учетом вышесказанного, есть несколько способов, которыми (формально) контекст выполнения (или просто контекст безопасности) не передается по потокам. Поведение по умолчанию заключается в том, что контекст передается - поэтому что-то должно влиять на это.

1) Нечто установило ExecutionContext.SuppressFlow() - Вы можете проверить это, сбросив значение ExecutionContext.IsFlowSuppressed() внутри задачи.

2) Есть элемент конфигурации <legacyImpersonationPolicy> (conifguration->runtime->legacyImpersonationPolicy) по умолчанию false, когда false WindowsIdentity передается через асинхронные точки. когда true это не так. Это не зависит от настроек потока ExecutionContext. Так true Здесь возникнет проблема для вас. Вы можете проверить это, сбросив значение SecurityContext.IsWindowsIdentityFlowSuppressed() это ваша задача. Это также может быть программно установлено для каждого потока с SecurityContext.SuppressFlowWindowsIdentity(),

Наконец, для полноты, если вы используете неуправляемый код, есть еще один параметр <alwaysFlowImpersonationPolicy> это управляет тем, как олицетворенные учетные данные передаются и в неуправляемых сценариях; другие описанные настройки влияют только на управляемый код.

На случай, если кто-то еще столкнется с этой проблемой... моя была немного другой. Моя служба WCF представлена ​​как служба REST, а также как SOAP, с контекстом безопасности, полученным из System.Web.HttpContext.Current или System.ServiceModel.OperationContext.Current. Мой DAL использует один из этих контекстов для идентификации текущего пользователя, проверив HttpContext.Current.User.Identity или OperationContext.Current.ClaimsPrincipal.Identity.

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

var httpcontext = System.Web.HttpContext.Current;
var opcontext = System.ServiceModel.OperationContext.Current;
Parallel.ForEach(types, (p) =>
{
    System.Web.HttpContext.Current = httpcontext;
    System.ServiceModel.OperationContext.Current = opcontext;

    // DO YOUR PARALLEL PROCESSING HERE
});
Другие вопросы по тегам