Frage

Ich habe eine Silverlight 2-Anwendung geschrieben, die mit einem WCF-Dienst (BasicHttpBinding) kommuniziert.Die Website, die den Silverlight-Inhalt hostet, ist durch einen ASP.NET-Mitgliedschaftsanbieter geschützt.Ich kann über HttpContext.Current.User.Identity.Name von meinem WCF-Dienst aus auf den aktuellen Benutzer zugreifen und habe AspNetCompatibilityRequirementsMode aktiviert.

Ich möchte jetzt eine Windows-Anwendung schreiben, die genau denselben Webdienst verwendet.Um die Authentifizierung zu handhaben, habe ich die aktiviert Authentifizierungsdienst, und kann „login“ aufrufen, um meinen Benutzer zu authentifizieren ...Okay, alles gut...Aber wie zum Teufel bekomme ich das Authentifizierungs-Cookie auf meinem anderen Service-Client gesetzt?!

Beide Dienste werden auf derselben Domäne gehostet

  • MyDataService.svc <- derjenige, der sich mit meinen Daten befasst
  • AuthenticationService.svc <- derjenige, den die Windows-App zur Authentifizierung aufrufen muss.

Ich möchte keinen neuen Dienst für den Windows-Client erstellen oder eine andere Bindung verwenden ...

Die Client Application Services sind eine weitere Alternative, aber alle Beispiele beschränken sich darauf, zu zeigen, wie man den Benutzer, die Rollen und sein Profil erhält ...Sobald wir jedoch mithilfe der Clientanwendungsdienste authentifiziert sind, sollte es eine Möglichkeit geben, dieses Authentifizierungscookie an meine Dienstclients anzuhängen, wenn ich denselben Server zurückrufe.

Laut Angaben von Kollegen besteht die Lösung darin, einen wsHttpBinding-Endpunkt hinzuzufügen, aber ich hoffe, dass ich das umgehen kann ...

War es hilfreich?

Lösung

ich endlich einen Weg gefunden, diese Arbeit zu machen. Für die Authentifizierung verwende ich den „ WCF-Authentifizierungsdienst “. Wenn der Dienst authentifiziert werden versuchen, einen Authentifizierungs-Cookie zu setzen. Ich brauche dieses Cookie, um aus der Antwort, und fügen Sie sie auf andere zu anderen Web-Services auf der gleichen Maschine hergestellt Anfrage. Der Code, das zu tun wie folgt aussieht:

var authService = new AuthService.AuthenticationServiceClient();
var diveService = new DiveLogService.DiveLogServiceClient();

string cookieHeader = "";
using (OperationContextScope scope = new OperationContextScope(authService.InnerChannel))
{
    HttpRequestMessageProperty requestProperty = new HttpRequestMessageProperty();
    OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = requestProperty;
    bool isGood = authService.Login("jonas", "jonas", string.Empty, true);
    MessageProperties properties = OperationContext.Current.IncomingMessageProperties;
    HttpResponseMessageProperty responseProperty = (HttpResponseMessageProperty)properties[HttpResponseMessageProperty.Name];
    cookieHeader = responseProperty.Headers[HttpResponseHeader.SetCookie];                
}

using (OperationContextScope scope = new OperationContextScope(diveService.InnerChannel))
{
    HttpRequestMessageProperty httpRequest = new HttpRequestMessageProperty();
    OperationContext.Current.OutgoingMessageProperties.Add(HttpRequestMessageProperty.Name, httpRequest);
    httpRequest.Headers.Add(HttpRequestHeader.Cookie, cookieHeader);
    var res = diveService.GetDives();
}      

Wie Sie sehen, habe ich zwei Service-Clients haben, eine fo den Authentifizierungsdienst, und eine für den Dienst, den ich werde tatsächlich nutzen. Der erste Block wird die Login-Methode, aufrufen und das Authentifizierungs-Cookie aus der Reaktion greifen. Der zweite Block wird der Header der Anforderung hinzufügen, bevor die „GetDives“ Service-Methode aufgerufen wird.

Ich bin nicht glücklich mit diesem Code überhaupt, und ich denke, eine bessere Alternative sein könnte „Web Reference“ anstelle von „Service Reference“ und verwenden Sie den .NET 2.0-Stack statt zu verwenden.

Andere Tipps

Web-Services, wie die von WCF erstellt, sind am besten oft in einem „stateless“ Art und Weise verwendet, so dass jeder Aufruf an einen Web-Service beginnt von neuem. Dies vereinfacht den Server-Code, da es keine Notwendigkeit, eine „Sitzung“ zu haben, die den Zustand des Client erinnert. Es vereinfacht auch den Client-Code, da es keine Notwendigkeit, Tickets, Cookies oder andere geegaws zu halten, die etwas über den Zustand des Servers übernehmen.

Erstellen von zwei Dienste in der Art und Weise, die beschrieben wird, führt Statusbehaftung. Der Client ist entweder „authentifiziert“ oder „nicht authentifiziert“, und die MyDataService.svc hat, um herauszufinden, welche.

Wie es passiert, ich habe WCF gefunden gut zu arbeiten, wenn der Mitgliedschaftsanbieter verwendet wird, zu authentifizieren alle zu einem Dienst aufrufen. So werden in dem Beispiel gegeben, würden Sie wollen den Mitgliedschaftsanbieter Authentifizierung gubbins an die Servicekonfiguration für MyDataService hinzuzufügen, und keinen separaten Authentifizierungsdienst hat überhaupt.

Weitere Informationen finden Sie im MSDN-Artikel hier .

[Was ist das für mich sehr attraktiv ist, wie ich faul bin, ist, dass dies völlig deklarative ist. Ich habe einfach streuen die richtigen Konfigurationseinträge für meine MembershipProvider in der app.config für die Anwendung und! Bingo! alle Anrufe in dem Dienst für jeden Vertrag authentifiziert.]

Es ist fair zu beachten, dass dies wird nicht besonders schnell sein. Wenn Sie SQL Server für Ihre Authentifizierung Datenbank verwenden werden Sie mindestens eine, vielleicht zwei gespeicherte Prozeduraufrufe pro Servicecall haben. In vielen Fällen (vor allem für HTTP-Bindungen) den Overhead des Dienstes nennen sich größer sein wird; Wenn nicht, sollten Sie Ihre eigene Implementierung eines Mitgliedschaftsanbieters rollend, die Authentifizierungsanforderungen zwischenspeichert.

Eine Sache, dass diese nicht gibt, ist die Fähigkeit, eine „Login“ Fähigkeit zur Verfügung zu stellen. Dafür können Sie entweder bieten einen (authentifizierte!) Service-Vertrag, den nichts tut (außer einen Fehler auslösen, wenn die Authentifizierung fehlschlägt), oder Sie können den Mitgliedschaftsanbieter-Dienst verwenden wie in dem ursprünglichen angegebenen Artikel beschrieben.

auf dem Client ändern Sie Ihre -Tag für den Dienst (innerhalb von ) enthalten: AllowCookies = "true"

Die App sollte jetzt das Cookie persistieren und nutzen. Sie werden bemerken, dass IsLoggedIn kehrt nun wahr nach der Anmeldung -. Es gibt false zurück, wenn Sie keine Cookies erlaubt

Es ist möglich, einen Großteil des zusätzlichen Code hinter einem benutzerdefinierten Nachrichteninspektoren & Verhalten zu verbergen, so dass Sie sich nicht nehmen müssen vorsichtig mit der Operation Bastelei.

Ich werde versuchen, etwas später zu verspotten und schicken es Ihnen.

- larsw

Sie sollten einen Blick auf die Cookie Objekt in System.Net. Diese Aufgabe kann ein Nicht-Browser-Client zu Cookies hängen. Dies ist, was mein Team, das letzte Mal haben wir in diesem Problem lief.

Hier ist ein kurze Artikel , wie etwa mit ihm zu gehen. Es kann da draußen bessere, aber das sollten Sie beginnen.

Wir gingen dem staatenlos Weg für unseren aktuellen Satz von WCF-Diensten und Silverlight 2-Anwendung. Es ist möglich, Silverlight 2 arbeitet mit Dienstleistungen mit TransportWithMessageCredential Sicherheit gebunden zu bekommen, obwohl es einigen benutzerdefinierten Sicherheitscode auf der Silverlight Seite nimmt. Das Ergebnis ist, dass jede Anwendung die Dienste einfach, indem Sie den Benutzernamen und das Passwort in den Nachrichten-Header zugreifen können. Dies kann einmal in einer benutzerdefinierten IRequestChannel Implementierung durchgeführt werden, so dass Entwickler nie über die Einstellung der Werte selbst zu kümmern. Obwohl WCF hat eine einfache Möglichkeit haben für Entwickler, dies zu tun, die ich glaube, ist serviceProxy.Security.Username und serviceProxy.Security.Password oder etwas ähnlich einfach.

Ich schrieb dieses eine Weile zurück, wenn ich Client-Application Service wurde mit gegen Web-Service zu authentifizieren. Es verwendet eine Nachricht Inspektoren die Cookie-Header einzufügen. Es gibt eine Word-Datei mit einer Dokumentation und einem Demo-Projekt. Obwohl es nicht genau das, was Sie tun, es ist ziemlich nah. Sie können es herunterladen von hier .

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top