2009-05-26 5 views
6

Alle,ungültige oder abgelaufene Sicherheitskontext-Token in WCF Webservice

Ich habe einen WCF-Webdienst (lassen Sie sich genannten Service "B") unter IIS gehostet ein Dienstkonto (VM, Windows 2003 SP2) verwenden. Der Dienst macht einen Endpunkt verfügbar, der WSHttpBinding mit den Standardwerten außer maxReceivedMessageSize, maxBufferPoolSize, maxBufferSize und einigen der erhöhten Zeitüberschreitungen verwendet.

Der Webdienst wurde mithilfe des Visual Studio Load Test-Frameworks mit ungefähr 800 gleichzeitigen Benutzern getestet und hat alle Tests erfolgreich bestanden, ohne dass Ausnahmen ausgelöst wurden. Der Proxy im Komponententest wurde aus der Konfiguration erstellt.

Es gibt eine Sharepoint-Anwendung, die den Office SharePoint Server-Suchdienst zum Aufrufen der Webdienste "A" und "B" verwendet. Die Anwendung erhält Daten von Dienst "A", um eine Anforderung zu erstellen, die an Dienst "B" gesendet wird. Die Antwort von Dienst "B" wird für die Suche indiziert. Der Proxy wird programmgesteuert mithilfe der ChannelFactory erstellt.

Wenn Service "A" weniger als 10 Minuten dauert, sind die Anrufe zu Service "B" erfolgreich. Wenn der Dienst "A" jedoch länger dauert (~ 20 Minuten), rufen die Anrufe für den Dienst "B" die folgende Ausnahme auf:

Ausnahmebedingungsnachricht: Die andere Partei hat einen ungesicherten oder falsch gesicherten Fehler erhalten. Siehe die interne FaultException für den Fehlercode und das Detail. Inner Exception Message: Die Nachricht konnte nicht verarbeitet werden. Dies liegt höchstwahrscheinlich daran, dass die Aktion 'Namespace/OperationName' falsch ist oder weil die Nachricht ein ungültiges oder abgelaufenes Sicherheitskontext-Token enthält oder weil die Bindungen nicht übereinstimmen. Das Sicherheitskontext-Token wäre ungültig, wenn der Dienst den Kanal aufgrund von Inaktivität abgebrochen hat. Um zu verhindern, dass der Dienst inaktive Sitzungen vorzeitig abbricht, erhöhen Sie das Empfangszeitlimit für die Bindung des Dienstendpunkts.

Die Bindungseinstellungen sind identisch, die Zeit im Client-Server und im Web-Service-Server sind mit dem Windows-Zeitdienst synchronisiert, die gleiche Zeitzone.

Wenn ich auf dem Server suchen, wo Web-Service "B" gehostet wird, kann ich die folgenden Sicherheitsfehler sehen protokollieren:

Quelle: Sicherheit

Kategorie: Anmelden/Abmelden

Ereignis-ID : 537

Benutzer NT AUTHORITY \ SYSTEM

Anmeldung fehlgeschlagen:

Grund: Ein Fehler ist aufgetreten bei der Anmeldung

Typ Anmeldung: 3

Logon-Prozess: Kerberos

Authentifizierungspaket: Kerberos

Statuscode: 0xC000006D

Substatus Code: 0xC0000133

Nach dem Lesen einiger Blogs online, der Sta tus code bedeutet STATUS_LOGON_FAILURE und der Substatuscode bedeutet STATUS_TIME_DIFFERENCE_AT_DC. aber ich habe bereits sowohl die Server- als auch die Client-Uhren überprüft und sie sind synchronisiert.

Ich bemerkte auch, dass das Sicherheitstoken irgendwo im Client-Server zwischengespeichert zu sein scheint, weil sie einen anderen Prozess haben, der den Webdienst "B" mit dem gleichen Dienstkonto aufruft und Daten beim ersten Aufruf erfolgreich erhält. Dann starten sie den Prozess zum Aktualisieren der Suchdienstindizes des Office-Sharepoint-Servers und es schlägt fehl. Wenn sie dann den ersten Prozess erneut aufrufen, wird es ebenfalls fehlschlagen.

Hat jemand diese Art von Problemen erlebt oder irgendwelche Ideen?

Grüße,

--Damian

Antwort

1

Was ich glaube, hier passiert, ist, dass Ihr Kanal Timeout (wie Sie vermuten).

Wenn ich es richtig verstehe, ist es nicht die Anrufe Ein Service, der aus sind Timing, sondern B, Service vor Sie Ihren Betrieb anrufen.

Ich vermute, dass du deinen Kanal erstellen vor rufen Sie Service A statt gerade rechtzeitig (das heißt, bevor der Dienst B Aufruf). Sie sollten den Kanal (Proxy-Service-Client) erstellen, bevor Sie es verwenden wie:

AResponse aResp = null; 
BResponse bResp = null; 
using (ServiceAProxy proxyA = new ServiceAProxy()) 
{ 
    aResp = proxyA.DoServiceAWork(); 
    using (ServiceBProxy proxyB = new ServiceBProxy()) 
    { 
     bResp = proxyB.DoOtherork(aResp); 
    } 
} 
return bResp; 

Ich glaube jedoch, dass, wenn Sie über bekommen, dass Problem (Service B Timing out), werden Sie feststellen, dass Der Proxy der Sharepoint-App (der Service A) wird Timeout. Um dies zu beheben, möchten Sie möglicherweise Ihr Servicemodell von einer Anfrage-Antwort zu einem Publish-Subscribe-Modell ändern.

Mit den seit langem laufenden Diensten möchten Sie, dass Ihre Sharepoint-App Service A abonniert und Service A die Ergebnisse veröffentlichen kann, wenn es dazu bereit ist - unabhängig davon, wie lange es dauert.

Programmierung WCF Services (O'Reilly) von Juval Lowey, hat eine großartige Erklärung, und IDesign (Juval Unternehmen) veröffentlicht a great set of coding standards for WCF, sowie den Code für eine große Publish-Subscribe Framework.

Hoffe, das hilft, Assaf.

5

10 Minuten ist das Standard-Empfangszeitlimit. Wenn Sie für mehr als 10 Minuten einen nicht aktiven Proxy verwenden, wird die Sicherheitssitzung dieses Proxys vom Server abgebrochen. Aktivieren Sie die Protokollierung und Sie sehen dies im Diagnoseprotokoll des Servers. Die Fehlermeldung, die Sie gemeldet haben, passt für dieses Verhalten. Durchsuchen Sie Ihre Systemdiagnosedatei nach "SessionIdleManager". Wenn Sie es finden, ist das oben genannte Ihr Problem.

Probieren Sie es aus und setzen Sie den "setetSecurityContext =" false "für den Client und den Server.

3

Rufen Sie die Serviceoperation nicht in einer using-Anweisung auf. Anstatt ein Muster verwenden, wie zum Beispiel ...

client = new ServiceClient("Ws<binding>") 
try 
{ 
    client.Operation(x,y); 
    client.Close(); 
} 
catch() 
{ 
    client.Abort(); 
} 

Ich verstehe nicht, warum das funktioniert, aber ich würde vermuten, dass, wenn der Proxy in der Anweisung using den Gültigkeitsbereich verläßt, wird Schließen nicht genannt.Der Dienst wartet dann, bis receiveTimeout (für die Bindung) abgelaufen ist, und bricht dann die Verbindung ab, wodurch nachfolgende Aufrufe fehlschlagen.

+0

Ich habe aufgehört, mit Verwenden von Statment für Service zu arbeiten. Wenn ich es entsorgen muss, rufen Sie explizite ((IDispose) Service) .Dispose(); Schließlich –

+1

Das Problem mit der Anweisung using ist, dass, wenn Sie eine Ausnahme während des Aufrufs haben, die Verwendung Anweisung Dispose() auf dem Client aufrufen, die Close() auf dem zugrunde liegenden Kanal aufrufen wird. Da die Verbindung bereits fehlerhaft ist, wird dies eine weitere Ausnahme auslösen und somit wird die erste Ausnahme nie auftauchen. – flayn

0

Ich habe diesen Fehler gerade ausgelöst, indem ich etwas Dummes gemacht habe. Ich habe einen Komponententest, der das Systemdatum ändert, um einige zeitbasierte Funktionen zu testen. Und ich vermute, dass der scheinbare Zeitunterschied zwischen dem Zeitpunkt, als ich den Kontext erstellte und dem Aufruf meiner Methode (wegen der Änderungen am Systemdatum), etwas ablaufen ließ.