Pour l'authentification de base, j'ai implémenté une coutume HttpMessageHandler
basé sur l'exemple présenté dans le Darin Dimitrov la réponse ici: http://stackoverflow.com/a/11536349/270591
Le code crée une instance principal
de type GenericPrincipal
avec nom d'utilisateur et de rôles et jeux de ce principe à l'actuelle directrice de la discussion:
Thread.CurrentPrincipal = principal;
Plus tard, en ApiController
méthode, le principal peut être lu par l'accès à l'contrôleurs User
de la propriété:
public class ValuesController : ApiController
{
public void Post(TestModel model)
{
var user = User; // this should be the principal set in the handler
//...
}
}
Tout semblait aller bien jusqu'à ce que j'ai récemment ajouté une coutume MediaTypeFormatter
qui utilise l' Task
bibliothèque de la sorte:
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;
}
(J'ai cette approche pour commencer une tâche avec des Task.Factory.StartNew
en ReadFromStreamAsync
à partir d'un exemple de code. Est-il erroné et peut-être la seule raison du problème?)
Maintenant, "parfois" et pour moi, il semble être aléatoire - l' User
principal dans la méthode de contrôleur n'est pas le principal plus j'ai mis dans l'MessageHandler, c'est à dire le nom d'utilisateur, Authenticated
drapeau et les rôles sont tous perdus. La raison semble être que la coutume MediaTypeFormatter provoque un changement du fil entre MessageHandler et la méthode du contrôleur. J'ai confirmé cela en comparant les valeurs de Thread.CurrentThread.ManagedThreadId
dans le MessageHandler et de la méthode du contrôleur. "Parfois," ils sont différents et puis le principal est "perdu".
J'ai regardé maintenant pour une alternative à la mise Thread.CurrentPrincipal
quelque sorte à transférer le capital en toute sécurité à partir de la coutume MessageHandler à la méthode de contrôleur et dans ce blog propriétés de la demande sont utilisés:
request.Properties.Add(HttpPropertyKeys.UserPrincipalKey,
new GenericPrincipal(identity, new string[0]));
J'ai voulu tester, mais il semble que l' HttpPropertyKeys
de la classe (qui est dans l'espace de noms System.Web.Http.Hosting
) n'a pas d' UserPrincipalKey
des biens plus récents WebApi versions (release candidate et à la sortie de la version finale de la semaine dernière ainsi).
Ma question est: Comment puis-je modifier le dernier extrait de code ci-dessus afin que est travaille avec les WebAPI version? Ou plus généralement: Comment puis-je régler l'utilisateur principal personnalisé dans un MessageHandler et d'y accéder de manière fiable dans une méthode de contrôleur?
Modifier
Il est mentionné ici que "HttpPropertyKeys.UserPrincipalKey
... résout "MS_UserPrincipal"
", j'ai donc essayé d'utiliser:
request.Properties.Add("MS_UserPrincipal",
new GenericPrincipal(identity, new string[0]));
Mais il ne fonctionne pas comme je m'y attendais: L' ApiController.User
propriété ne contient pas la principale ajouté à l' Properties
de la collection ci-dessus.