Falscher Thread.CurrentPrincipal in der asynchronen WCF-Endmethode

8

Ich habe einen WCF-Dienst, dessen Thread.CurrentPrincipal in ServiceConfiguration.ClaimsAuthorizationManager festgelegt wurde.

Wenn ich den Service asynchron wie folgt implementiere:

%Vor%

Ich finde, dass das Thread.CurrentPrincipal in der Begin-Methode und auch in der WorkerFunction auf das richtige ClaimsPrincipal festgelegt ist, aber in der End-Methode ist es auf ein GenericPrincipal festgelegt.

Ich weiß, dass ich die ASP.NET-Kompatibilität für den Dienst aktivieren und HttpContext.Current.User verwenden kann, das in allen Methoden den richtigen Prinzipal hat, aber das möchte ich lieber nicht tun.

Gibt es eine Möglichkeit, das Thread.CurrentPrincipal zu dem richtigen ClaimsPrincipal zu zwingen, ohne ASP.NET-Kompatibilität zu aktivieren?

    
MvdD 08.01.2014, 23:08
quelle

3 Antworten

3

Beginnen Sie mit einer Zusammenfassung der WCF-Erweiterungspunkte Sehen Sie sich das an, das ausdrücklich darauf ausgelegt ist, Ihr Problem zu lösen. Es wird CallContextInitializer genannt. Werfen Sie einen Blick auf diese Artikel, der CallContextInitializer-Beispielcode gibt.

Wenn Sie eine ICallContextInitializer-Erweiterung erstellen, erhalten Sie die Kontrolle über den BeginXXX-Threadkontext AND den EndXXX-Threadkontext. Sie sagen, dass der ClaimsAuthorizationManager den Benutzerprinzipal in Ihrer BeginXXX-Methode (...) korrekt eingerichtet hat. In diesem Fall erstellen Sie dann einen benutzerdefinierten ICallContextInitializer, der das CurrentPrincipal entweder zuweist oder aufzeichnet, je nachdem, ob es Ihren BeginXXX () oder Ihren EndXXX () verarbeitet. Etwas wie:

%Vor%

Zur weiteren Klärung ziehen Sie zwei Fälle in Betracht. Angenommen, Sie haben sowohl einen ICallContextInitializer als auch einen IParameterInspector implementiert. Angenommen, diese Hooks werden voraussichtlich mit einem synchronen WCF-Dienst und mit einem asynchronen WCF-Dienst ausgeführt (was Ihr Spezialfall ist).

Im Folgenden sind die Abfolge der Ereignisse und die Erklärung dessen, was passiert:

Synchroner Fall

%Vor%

Nichts überraschendes im obigen Code. Aber schauen Sie sich jetzt an, was mit asynchronen Service-Operationen passiert ...

Asynchroner Fall

%Vor%

Wie Sie sehen, stellt der CallContextInitializer sicher, dass Sie die Möglichkeit haben, Werte wie Ihren CurrentPrincipal kurz vor der Ausführung der EndXXX () - Routine zu initialisieren. Es spielt also keine Rolle, dass die Routine EndXXX () mit Sicherheit in einem anderen Thread ausgeführt wird als die Routine BeginXXX (). Und ja, das System.ServiceModel.Channels.Message -Objekt, das Ihren Benutzerprinzipal zwischen Begin / End-Methoden speichert, wird von WCF beibehalten und korrekt übertragen, obwohl sich der Thread geändert hat.

Insgesamt ermöglicht dieser Ansatz, dass EndXXX (IAsyncresult) mit dem korrekten IPrincipal ausgeführt wird, ohne das CurrentPrincipal in der EndXXX () - Routine explizit neu erstellen zu müssen. Wie bei jedem WCF-Verhalten können Sie entscheiden, ob dies für einzelne Vorgänge, für alle Vorgänge an einem Vertrag oder für alle Vorgänge an einem Endpunkt gilt.

    
Brent Arias 13.01.2014, 00:26
quelle
1

Nicht wirklich die Antwort auf meine Frage, aber ein alternativer Ansatz zur Implementierung des WCF-Dienstes (in .NET 4.5), der nicht die gleichen Probleme mit Thread.CurrentPrincipal aufweist.

%Vor%     
MvdD 16.01.2014 22:41
quelle
0

Der gültige Ansatz dazu ist, eine Erweiterung zu erstellen:

%Vor%

Diese Erweiterung wird jetzt als Container für Objekte verwendet, die zwischen den Thread-Wechseln beibehalten werden sollen, da OperationContext.Current gleich bleibt.

Jetzt können Sie dies in BeginMethod1 verwenden, um den aktuellen Benutzer zu speichern:

%Vor%

Und dann in EndMethod1 können Sie den Benutzer erhalten, indem Sie eingeben:

%Vor%

BEARBEITEN (ein anderer Ansatz):

%Vor%     
Admir Tuzović 11.01.2014 09:17
quelle