Как я могу безопасно установить пользователя в пользовательском WebAPI HttpMessageHandler?

Для базовой аутентификации я реализовал кастомHttpMessageHandler основываясь на примере, показанном в ответе Дарина Димитрова здесь:https://stackoverflow.com/a/11536349/270591

Код создает экземплярprincipal типаGenericPrincipal с именем пользователя и ролями, а затем устанавливает этот принципал для текущего участника потока:

Thread.CurrentPrincipal = principal;

Позже вApiController Метод принципала может быть прочитан путем доступа к контроллерамUser имущество:

public class ValuesController : ApiController
{
    public void Post(TestModel model)
    {
        var user = User; // this should be the principal set in the handler
        //...
    }
}

Это, казалось, работало нормально, пока я недавно не добавил кастомMediaTypeFormatter который используетTask библиотека вроде так:

public override Task<object> ReadFromStreamAsync(Type type, Stream readStream,
    HttpContent content, IFormatterLogger formatterLogger)
{
    var task = Task.Factory.StartNew(() =>
    {
        // some formatting happens and finally a TestModel is returned,
        // simulated here by just an empty model
        return (object)new TestModel();
    });
    return task;
}

(У меня есть такой подход, чтобы начать задачу сTask.Factory.StartNew вReadFromStreamAsync из некоторого примера кода. Это неправильно и, возможно, единственная причина проблемы?)

Теперь «иногда» - и для меня это кажется случайным -User принципал в методе контроллера больше не является принципалом, который я установил в MessageHandler, то есть имя пользователя,Authenticated флаг и роли все потеряны. Кажется, причина в том, что пользовательский MediaTypeFormatter вызывает изменение потока между MessageHandler и методом контроллера. Я подтвердил это путем сравнения значенийThread.CurrentThread.ManagedThreadId в MessageHandler и в методе контроллера. & Quot; Иногда & Quot; они различаются, и тогда основной элемент "теряется".

Я искал альтернативу настройкеThread.CurrentPrincipal каким-то образом безопасно передать принципал из пользовательского MessageHandler в метод контроллера и вэтот блог Свойства запроса используются:

request.Properties.Add(HttpPropertyKeys.UserPrincipalKey,
    new GenericPrincipal(identity, new string[0]));

Я хотел проверить это, но кажется, чтоHttpPropertyKeys класс (который находится в пространстве именSystem.Web.Http.Hosting) не имеетUserPrincipalKey свойство больше в последних версиях WebApi (кандидат на выпуск и финальный выпуск также на прошлой неделе).

У меня вопрос: как я могу изменить последний фрагмент кода выше, чтобы он работал с текущей версией WebAPI? Или вообще: как я могу установить пользователя в пользовательском MessageHandler и получить к нему надежный доступ с помощью метода контроллера?

Edit

УпоминаетсяВот это & quot;HttpPropertyKeys.UserPrincipalKey ... решает в“MS_UserPrincipal”& quot ;, поэтому я попытался использовать:

request.Properties.Add("MS_UserPrincipal",
    new GenericPrincipal(identity, new string[0]));

Но это не работает, как я ожидал:ApiController.User свойство не содержит принципала, добавленного кProperties Коллекция выше.

Ответы на вопрос(3)

Ваш ответ на вопрос