Benutzerdefinierte Stream-Upgrades

Streamorientierte Transports wie TCP und benannte Pipes werden auf einem fortlaufenden Bytestream zwischen Client und Server ausgeführt. Dieser Stream wird durch ein Stream-Objekt realisiert. Bei einem Stream-Upgrade will der Client dem Kanalstapel eine optionale Protokollebene hinzufügen und fordert das andere Ende des Kommunikationskanals dazu auf. Das Stream-Upgrade besteht aus dem Ersetzen des ursprünglichen Stream-Objekts durch ein aktualisiertes Objekt.

Sie können z. B. einen Komprimierungsstream direkt über dem Transportstream erstellen. In diesem Fall wird der ursprüngliche Transport-Stream durch einen Stream ersetzt, der den ursprünglichen Stream mit dem Komprimierungs-Stream umschließt.

Sie können mehrere Stream-Upgrades implementieren, die das jeweils vorangehende Upgrade umschließen.

Funktionsweise von Stream-Upgrades

Der Stream-Upgrade-Prozess besteht aus vier Komponenten.

  1. Der Vorgang wird mit einem Initiator für den Upgrade-Stream gestartet: Er kann zur Laufzeit eine Anforderung an das andere Ende der Verbindung zum Upgrade der Kanaltransportebene initialisieren.

  2. Ein Annehmender für den Upgrade-Stream führt das Upgrade aus: Er empfängt zur Laufzeit die Upgradeanforderung von dem anderen Computer und akzeptiert ggf. das Upgrade.

  3. Ein Upgradeanbieter erstellt den Initiator auf dem Client und den Annehmenden auf dem Server.

  4. Ein Bindungselement für das Stream-Upgrade wird den Bindungen auf dem Dienst und dem Client hinzugefügt und erstellt zur Laufzeit den Anbieter.

Bei mehreren Upgrades kapseln der Initiator und der Annehmende Zustandsautomaten, um zu erzwingen, welche Upgradeübergänge für jede Initiierung gültig sind.

So implementieren Sie ein Streamupgrade

Windows Communication Foundation (WCF) stellt vier abstract Klassen bereit, die Sie implementieren können:

Gehen Sie wie folgt vor, um ein benutzerdefiniertes Streamupgrade zu implementieren. Bei dieser Prozedur wird ein minimaler Streamupgradevorgang auf den Client- und Servercomputern implementiert.

  1. Erstellen Sie eine Klasse, die das StreamUpgradeInitiator implementiert.

    1. Überschreiben Sie die InitiateUpgrade-Methode, um den zu aktualisierenden Stream anzugeben, und geben Sie den aktualisierten Stream zurück. Diese Methode funktioniert synchron; es gibt analoge Methoden, um das Upgrade asynchron zu initiieren.

    2. Überschreiben Sie die GetNextUpgrade-Methode, um zusätzliche Upgrades zu suchen.

  2. Erstellen Sie eine Klasse, die das StreamUpgradeAcceptor implementiert.

    1. Überschreiben Sie die AcceptUpgrade-Methode, um den zu aktualisierenden Stream anzugeben, und geben Sie den aktualisierten Stream zurück. Diese Methode funktioniert synchron; es gibt analoge Methoden, um das Upgrade asynchron anzunehmen.

    2. Überschreiben Sie die CanUpgrade-Methode, um festzulegen, ob das angeforderte Upgrade von dem Annehmenden des Upgrades an dieser Stelle im Upgradeprozess unterstützt wird.

  3. Erstellen Sie eine Klasse, die den StreamUpgradeProvider implementiert. Überschreiben Sie die CreateUpgradeAcceptor-Methode und die CreateUpgradeInitiator-Methode, um Instanzen des in Schritt 1 und 2 definierten Annehmenden und Initiators zurückzugeben.

  4. Erstellen Sie eine Klasse, die das StreamUpgradeBindingElement implementiert.

    1. Überschreiben Sie die BuildClientStreamUpgradeProvider-Methode auf dem Client und die BuildServerStreamUpgradeProvider-Methode auf dem Dienst.

    2. Überschreiben Sie die BuildChannelFactory-Methode auf dem Client und die BuildChannelListener-Methode auf dem Dienst, um das Upgrade-Bindungselement zu BindingParameters hinzuzufügen.

  5. Fügen Sie das neue Stream-Upgrade-Bindungselement Bindungen auf den Server- und Clientcomputern hinzu.

Sicherheitsupgrades

Das Hinzufügen eines Sicherheitsupgrades ist eine spezielle Version des allgemeinen Stream-Upgrade-Prozesses.

WCF stellt bereits zwei Bindungselemente für das Upgrade von Stream Security. Die Konfiguration der Sicherheit auf Transportebene wird durch das WindowsStreamSecurityBindingElement und das SslStreamSecurityBindingElement gekapselt, die konfiguriert und einer benutzerdefinierten Bindung hinzugefügt werden können. Diese Bindungselemente erweitern die StreamUpgradeBindingElement-Klasse, die den Client- und Server-Stream-Upgrade-Anbieter erstellt. Diese Bindungselements enthalten Methoden zum Erstellen der speziellen Upgradeanbieterklassen für Sicherheitsstream, die nicht public sind, in diesen beiden Fällen müssen Sie lediglich das Bindungselement der Bindung hinzufügen.

Bei Sicherheitsszenarien, die die beiden oben angeführten Bindungselemente nicht erfüllen, werden drei sicherheitsrelevante abstract-Klassen von den oben genannten Basisklassen für Initiator, Annehmender und Anbieter abgeleitet:

  1. System.ServiceModel.Channels.StreamSecurityUpgradeInitiator

  2. System.ServiceModel.Channels.StreamSecurityUpgradeAcceptor

  3. System.ServiceModel.Channels.StreamSecurityUpgradeProvider

Der Vorgang zum Implementieren eines Security Stream-Upgrades ist der gleiche wie zuvor, mit dem Unterschied, dass Sie von diesen drei Klassen ableiten. Überschreiben Sie die zusätzlichen Eigenschaften in diesen Klassen, um Sicherheitsinformationen zur Laufzeit anzugeben.

Mehrere Upgrades

Wiederholen Sie zum Erstellen zusätzlicher Upgradeanforderungen den oben aufgeführten Vorgang: Erstellen Sie zusätzliche Erweiterungen von StreamUpgradeProvider und Bindungselemente. Fügen Sie die Bindungselemente der Bindung hinzu. Die zusätzlichen Bindungselemente werden nacheinander verarbeitet, beginnend mit dem ersten der Bindung hinzugefügten Bindungselement. In BuildChannelFactory und BuildChannelListener kann jeder Upgradeanbieter die eigene Anordnung auf bereits vorhandene Upgradebindungsparameter festlegen. Anschließend muss der vorhandene Upgradebindungsparameter durch einen neuen zusammengesetzten Upgradebindungsparameter ersetzt werden.

Alternativ kann ein Upgradeanbieter mehrere Upgrades unterstützen. Sie können z. B. einen benutzerdefinierten Stream-Upgrade-Anbieter implementieren, der Sicherheit und Komprimierung unterstützt. Führen Sie die folgenden Schritte aus:

  1. Bilden Sie eine Unterklasse für den StreamSecurityUpgradeProvider, um die Anbieterklasse zu schreiben, die den Initiator und Annehmenden erstellt.

  2. Bilden Sie eine Unterklasse für den StreamSecurityUpgradeInitiator, und überschreiben Sie die GetNextUpgrade-Methode, um die Inhaltstypen für den Komprimierungsstream und den sicheren Stream nacheinander zurückzugeben.

  3. Bilden Sie eine Unterklasse für den StreamSecurityUpgradeAcceptor, der die benutzerdefinierten Inhaltstypen in seiner CanUpgrade-Methode lesen kann.

  4. Der Stream wird nach jedem Aufruf an GetNextUpgrade und CanUpgrade aktualisiert.

Siehe auch