For basic authentication, I implemented a custom HttpMessageHandler based on the example shown in Darina Dimitrov, here: https://stackoverflow.com/a/464829/
The code creates an instance of principal type GenericPrincipal with username and roles, and then sets this principle to the current principle of the stream:
Thread.CurrentPrincipal = principal;
Later in the ApiController method ApiController principal can be read by accessing the properties of the User controllers:
public class ValuesController : ApiController { public void Post(TestModel model) { var user = User;
This seemed like normal until I recently added a custom MediaTypeFormatter which uses the Task library as follows:
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; }
(I have such an approach to start a task from Task.Factory.StartNew in ReadFromStreamAsync from some sample code. Is this wrong and maybe the only reason for the problem?)
Now "sometimes" - and for me it seems random - the User principle in the controller method is no longer the main one that I set in MessageHandler, that is, the username, Authenticated and roles are lost. The reason is that the custom MediaTypeFormatter causes a thread change between the MessageHandler and the controller method. I confirmed this by comparing the values ββof Thread.CurrentThread.ManagedThreadId in the MessageHandler and in the controller method. "Sometimes," they are different, and then "lost."
Now I was looking for an alternative to setting Thread.CurrentPrincipal to somehow pass the principal safely from the custom MessageHandler to the controller method and to this blog post :
request.Properties.Add(HttpPropertyKeys.UserPrincipalKey, new GenericPrincipal(identity, new string[0]));
I wanted to check this out, but it seems that the HttpPropertyKeys class (which is in the System.Web.Http.Hosting ) no longer has the UserPrincipalKey property in recent versions of WebApi (release candidate and final release from last week as well).
My question is: how can I change the last code snippet above to work with the current version of WebAPI? Or in general: how can I set a user principle in a custom MessageHandler and reliably get it in a controller method?
Edit
It is mentioned here that " HttpPropertyKeys.UserPrincipalKey ... resolves "MS_UserPrincipal" ", so I tried using:
request.Properties.Add("MS_UserPrincipal", new GenericPrincipal(identity, new string[0]));
But it does not work as I expected: the ApiController.User property ApiController.User not contain the principal added to the Properties collection above.