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.

Antworten auf die Frage(3)

Ihre Antwort auf die Frage