Как я могу безопасно установить пользователя в пользовательском 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
Коллекция выше.