Wie kann ich den Benutzerprinzipal sicher in einem benutzerdefinierten WebAPI-HttpMessageHandler festlegen?
Für die Basisauthentifizierung habe ich eine benutzerdefinierte implementiertHttpMessageHandler
basierend auf dem Beispiel in Darin Dimitrovs Antwort hier:https://stackoverflow.com/a/11536349/270591
Der Code erstellt eine Instanzprincipal
vom TypGenericPrincipal
mit Benutzername und Rollen und setzt dann diesen Principal auf den aktuellen Principal des Threads:
Thread.CurrentPrincipal = principal;
Später in einemApiController
Methode kann der Principal durch Zugriff auf die Controller gelesen werdenUser
Eigentum:
public class ValuesController : ApiController
{
public void Post(TestModel model)
{
var user = User; // this should be the principal set in the handler
//...
}
}
Dies schien gut zu funktionieren, bis ich kürzlich einen Brauch hinzufügteMediaTypeFormatter
das nutzt dieTask
Bibliothek so:
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;
}
(Ich habe diesen Ansatz, um eine Aufgabe mit zu beginnenTask.Factory.StartNew
imReadFromStreamAsync
aus einem Beispielcode. Ist es falsch und vielleicht der einzige Grund für das Problem?)
Nun, "manchmal" - und für mich scheint es zufällig zu sein - dasUser
Prinzipal in der Controller-Methode ist nicht mehr das Prinzipal, das ich im MessageHandler festgelegt habe, d. h. Benutzername,Authenticated
Flagge und Rollen sind alle verloren. Der Grund scheint zu sein, dass der benutzerdefinierte MediaTypeFormatter eine Änderung des Threads zwischen MessageHandler- und Controller-Methode verursacht. Ich habe dies durch Vergleichen der Werte von bestätigtThread.CurrentThread.ManagedThreadId
im MessageHandler und in der Controller-Methode. "Manchmal" sind sie anders und dann ist der Auftraggeber "verloren".
Ich habe jetzt nach einer Alternative zum Einstellen gesuchtThread.CurrentPrincipal
um den Principal sicher vom benutzerdefinierten MessageHandler auf die Controller-Methode und in zu übertragendieser Blogbeitrag Anfrageeigenschaften werden verwendet:
request.Properties.Add(HttpPropertyKeys.UserPrincipalKey,
new GenericPrincipal(identity, new string[0]));
Ich wollte das testen, aber es scheint, dass dieHttpPropertyKeys
Klasse (die im Namespace istSystem.Web.Http.Hosting
) hat keineUserPrincipalKey
Eigenschaft nicht mehr in den aktuellen WebApi-Versionen (Release Candidate und endgültiges Release von letzter Woche).
Meine Frage ist: Wie kann ich das letzte Codefragment oben ändern, damit es mit der aktuellen WebAPI-Version funktioniert? Oder allgemein: Wie kann ich den Benutzerprinzipal in einem benutzerdefinierten MessageHandler festlegen und in einer Controllermethode zuverlässig darauf zugreifen?
Bearbeiten
Es wird erwähntHier Das "HttpPropertyKeys.UserPrincipalKey
... beschließt zu“MS_UserPrincipal”
", also habe ich versucht zu benutzen:
request.Properties.Add("MS_UserPrincipal",
new GenericPrincipal(identity, new string[0]));
Aber es funktioniert nicht so, wie ich es erwartet hatte:ApiController.User
Die Eigenschaft enthält nicht den Principal, der der Eigenschaft hinzugefügt wurdeProperties
Sammlung oben.