对于基本身份验证我实现了自定义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,并在控制器方法。 “有时候,”他们是不同的,然后本金“丢失”。
我现在已经找了一个替代设置Thread.CurrentPrincipal
以某种方式安全地从自定义的MessageHandler转移校长到控制器的方法,并在这个博客帖子请求属性使用:
request.Properties.Add(HttpPropertyKeys.UserPrincipalKey,
new GenericPrincipal(identity, new string[0]));
我想测试,但它似乎HttpPropertyKeys
类(在命名空间System.Web.Http.Hosting
)不具有UserPrincipalKey
在最近的WebAPI的版本属性了(上周发布候选版和最终版本以及) 。
我的问题是:如何更改上面的最后一个代码段,这样与当前的WebAPI版本的作品? 或一般:我怎样才能设置用户主要在自定义的MessageHandler和访问的可靠性是控制器的方法?
编辑
它提到这里是“ HttpPropertyKeys.UserPrincipalKey
...解析为“MS_UserPrincipal”
”,所以我试图用:
request.Properties.Add("MS_UserPrincipal",
new GenericPrincipal(identity, new string[0]));
但是,如我所料不工作: ApiController.User
属性不包含本金加到Properties
集以上。