Overzicht: Aangepaste client- en servicereferenties maken
In dit onderwerp wordt beschreven hoe u aangepaste client- en servicereferenties implementeert en hoe u aangepaste referenties uit toepassingscode gebruikt.
Klassen Uitbreidbaarheid van referenties
De ClientCredentials en ServiceCredentials klassen zijn de belangrijkste toegangspunten voor de uitbreidbaarheid van de Beveiliging van Windows Communication Foundation (WCF). Deze referentieklassen bieden de API's waarmee toepassingscode referentiegegevens kan instellen en referentietypen kan converteren naar beveiligingstokens. (Beveiligingstokens zijn het formulier dat wordt gebruikt voor het verzenden van referentiegegevens in SOAP-berichten.) De verantwoordelijkheden van deze referentieklassen kunnen worden onderverdeeld in twee gebieden:
Geef de API's op voor toepassingen om referenties in te stellen.
Als een fabriek uitvoeren voor SecurityTokenManager implementaties.
De standaard implementaties in WCF ondersteunen de door het systeem geleverde referentietypen en maken een beveiligingstokenbeheerder die deze typen referenties kan verwerken.
Redenen om aan te passen
Er zijn meerdere redenen voor het aanpassen van client- of servicereferentieklassen. Vooral is de vereiste om het standaard WCF-beveiligingsgedrag te wijzigen met betrekking tot het verwerken van door het systeem geleverde referentietypen, met name om de volgende redenen:
Wijzigingen die niet mogelijk zijn met andere uitbreidbaarheidspunten.
Nieuwe referentietypen toevoegen.
Nieuwe aangepaste beveiligingstokentypen toevoegen.
In dit onderwerp wordt beschreven hoe u aangepaste client- en servicereferenties implementeert en hoe u deze kunt gebruiken vanuit toepassingscode.
Eerst in een reeks
Het maken van een aangepaste referentieklasse is alleen de eerste stap, omdat de reden voor het aanpassen van referenties is het wijzigen van WCF-gedrag met betrekking tot het inrichten van referenties, het serialiseren van beveiligingstokens of verificatie. In andere onderwerpen in deze sectie wordt beschreven hoe u aangepaste serializers en verificators maakt. In dit opzicht is het maken van een aangepaste referentieklasse het eerste onderwerp in de reeks. Volgende acties (het maken van aangepaste serializers en verificators) kunnen alleen worden uitgevoerd nadat u aangepaste referenties hebt gemaakt. Aanvullende onderwerpen die voortbouwen op dit onderwerp zijn onder andere:
Procedures
Aangepaste clientreferenties implementeren
Definieer een nieuwe klasse die is afgeleid van de ClientCredentials klasse.
Optioneel. Voeg nieuwe methoden of eigenschappen toe voor nieuwe referentietypen. Als u geen nieuwe referentietypen toevoegt, slaat u deze stap over. In het volgende voorbeeld wordt een
CreditCardNumber
eigenschap toegevoegd.Overschrijf de CreateSecurityTokenManager methode. Deze methode wordt automatisch aangeroepen door de WCF-beveiligingsinfrastructuur wanneer de aangepaste clientreferentie wordt gebruikt. Deze methode is verantwoordelijk voor het maken en retourneren van een exemplaar van een implementatie van de SecurityTokenManager klasse.
Belangrijk
Het is belangrijk te weten dat de CreateSecurityTokenManager methode wordt overschreven om een aangepast beveiligingstokenbeheer te maken. De beveiligingstokenbeheer, afgeleid van ClientCredentialsSecurityTokenManager, moet een aangepaste beveiligingstokenprovider retourneren, afgeleid van SecurityTokenProvider, om het werkelijke beveiligingstoken te maken. Als u dit patroon niet volgt voor het maken van beveiligingstokens, werkt uw toepassing mogelijk onjuist wanneer ChannelFactory objecten in de cache worden opgeslagen (dit is het standaardgedrag voor WCF-clientproxy's), wat mogelijk resulteert in een uitbreiding van bevoegdheden. Het aangepaste referentieobject wordt in de cache opgeslagen als onderdeel van de ChannelFactory. De aangepaste SecurityTokenManager code wordt echter gemaakt bij elke aanroep, waardoor de beveiligingsrisico's worden beperkt zolang de logica voor het maken van tokens in de SecurityTokenManager.
Overschrijf de CloneCore methode.
public class MyClientCredentials : ClientCredentials { string creditCardNumber; public MyClientCredentials() { // Perform client credentials initialization. } protected MyClientCredentials(MyClientCredentials other) : base(other) { // Clone fields defined in this class. this.creditCardNumber = other.creditCardNumber; } public string CreditCardNumber { get { return this.creditCardNumber; } set { if (value == null) { throw new ArgumentNullException("value"); } this.creditCardNumber = value; } } public override SecurityTokenManager CreateSecurityTokenManager() { // Return your implementation of the SecurityTokenManager. return new MyClientCredentialsSecurityTokenManager(this); } protected override ClientCredentials CloneCore() { // Implement the cloning functionality. return new MyClientCredentials(this); } }
Public Class MyClientCredentials Inherits ClientCredentials Private creditCardNumberValue As String Public Sub New() End Sub ' Perform client credentials initialization. Protected Sub New(ByVal other As MyClientCredentials) MyBase.New(other) ' Clone fields defined in this class. Me.creditCardNumberValue = other.creditCardNumberValue End Sub Public Property CreditCardNumber() As String Get Return Me.creditCardNumberValue End Get Set If value Is Nothing Then Throw New ArgumentNullException("value") End If Me.creditCardNumberValue = value End Set End Property Public Overrides Function CreateSecurityTokenManager() As SecurityTokenManager ' Return your implementation of the SecurityTokenManager. Return New MyClientCredentialsSecurityTokenManager(Me) End Function Protected Overrides Function CloneCore() As ClientCredentials ' Implement the cloning functionality. Return New MyClientCredentials(Me) End Function End Class
Een aangepast clientbeveiligingstokenbeheer implementeren
Definieer een nieuwe klasse die is afgeleid van ClientCredentialsSecurityTokenManager.
Optioneel. Overschrijf de CreateSecurityTokenProvider(SecurityTokenRequirement) methode als er een aangepaste SecurityTokenProvider implementatie moet worden gemaakt. Zie How to: Create a Custom Security Token Provider (Een aangepaste beveiligingstokenprovider maken) voor meer informatie over aangepaste beveiligingstokenproviders.
Optioneel. Overschrijf de CreateSecurityTokenAuthenticator(SecurityTokenRequirement, SecurityTokenResolver) methode als er een aangepaste SecurityTokenAuthenticator implementatie moet worden gemaakt. Zie How to: Create a Custom Security Token Authenticator(Een aangepaste beveiligingstoken authenticator maken) voor meer informatie over aangepaste beveiligingstoken authenticators.
Optioneel. Overschrijf de CreateSecurityTokenSerializer methode als er een aangepaste SecurityTokenSerializer moet worden gemaakt. Zie Een aangepast token maken voor meer informatie over aangepaste beveiligingstokens en serializers voor aangepaste beveiligingstokens.
internal class MyClientCredentialsSecurityTokenManager : ClientCredentialsSecurityTokenManager { MyClientCredentials credentials; public MyClientCredentialsSecurityTokenManager(MyClientCredentials credentials) : base(credentials) { this.credentials = credentials; } public override SecurityTokenProvider CreateSecurityTokenProvider( SecurityTokenRequirement tokenRequirement) { // Return your implementation of the SecurityTokenProvider, if required. // This implementation delegates to the base class. return base.CreateSecurityTokenProvider(tokenRequirement); } public override SecurityTokenAuthenticator CreateSecurityTokenAuthenticator( SecurityTokenRequirement tokenRequirement, out SecurityTokenResolver outOfBandTokenResolver) { // Return your implementation of the SecurityTokenAuthenticator, if required. // This implementation delegates to the base class. return base.CreateSecurityTokenAuthenticator(tokenRequirement, out outOfBandTokenResolver); } public override SecurityTokenSerializer CreateSecurityTokenSerializer(SecurityTokenVersion version) { // Return your implementation of the SecurityTokenSerializer, if required. // This implementation delegates to the base class. return base.CreateSecurityTokenSerializer(version); } }
Friend Class MyClientCredentialsSecurityTokenManager Inherits ClientCredentialsSecurityTokenManager Private credentials As MyClientCredentials Public Sub New(ByVal credentials As MyClientCredentials) MyBase.New(credentials) Me.credentials = credentials End Sub Public Overrides Function CreateSecurityTokenProvider( _ ByVal tokenRequirement As SecurityTokenRequirement) As SecurityTokenProvider ' Return your implementation of the SecurityTokenProvider, if required. ' This implementation delegates to the base class. Return MyBase.CreateSecurityTokenProvider(tokenRequirement) End Function Public Overrides Function CreateSecurityTokenAuthenticator( _ ByVal tokenRequirement As SecurityTokenRequirement, _ ByRef outOfBandTokenResolver As SecurityTokenResolver) As SecurityTokenAuthenticator ' Return your implementation of the SecurityTokenAuthenticator, if required. ' This implementation delegates to the base class. Return MyBase.CreateSecurityTokenAuthenticator(tokenRequirement, outOfBandTokenResolver) End Function Public Overrides Function CreateSecurityTokenSerializer(ByVal version As SecurityTokenVersion) _ As SecurityTokenSerializer ' Return your implementation of the SecurityTokenSerializer, if required. ' This implementation delegates to the base class. Return MyBase.CreateSecurityTokenSerializer(version) End Function End Class
Een aangepaste clientreferenties gebruiken vanuit toepassingscode
Maak een exemplaar van de gegenereerde client die de serviceinterface vertegenwoordigt of maak een exemplaar van de ChannelFactory service die verwijst naar een service waarmee u wilt communiceren.
Verwijder het gedrag van de door het systeem geleverde clientreferenties uit de Behaviors verzameling, die toegankelijk is via de Endpoint eigenschap.
Maak een nieuw exemplaar van een aangepaste clientreferentieklasse en voeg deze toe aan de Behaviors verzameling, die toegankelijk is via de Endpoint eigenschap.
// Create a client with the client endpoint configuration. CalculatorClient client = new CalculatorClient(); // Remove the ClientCredentials behavior. client.ChannelFactory.Endpoint.Behaviors.Remove<ClientCredentials>(); // Add a custom client credentials instance to the behaviors collection. client.ChannelFactory.Endpoint.Behaviors.Add(new MyClientCredentials());
' Create a client with the client endpoint configuration. Dim client As New CalculatorClient() ' Remove the ClientCredentials behavior. client.ChannelFactory.Endpoint.Behaviors.Remove(Of ClientCredentials)() ' Add a custom client credentials instance to the behaviors collection. client.ChannelFactory.Endpoint.Behaviors.Add(New MyClientCredentials())
In de vorige procedure ziet u hoe u clientreferenties gebruikt vanuit toepassingscode. WCF-referenties kunnen ook worden geconfigureerd met behulp van het toepassingsconfiguratiebestand. Het gebruik van toepassingsconfiguratie verdient vaak de voorkeur aan hardcodering, omdat hiermee toepassingsparameters kunnen worden gewijzigd zonder dat u de bron, hercompilering en herconfiguratie hoeft te wijzigen.
In de volgende procedure wordt beschreven hoe u ondersteuning kunt bieden voor de configuratie van aangepaste referenties.
Een configuratie-handler maken voor aangepaste clientreferenties
Definieer een nieuwe klasse die is afgeleid van ClientCredentialsElement.
Optioneel. Voeg eigenschappen toe voor alle aanvullende configuratieparameters die u beschikbaar wilt maken via de toepassingsconfiguratie. In het onderstaande voorbeeld wordt één eigenschap met de naam
CreditCardNumber
toegevoegd.Overschrijf de BehaviorType eigenschap om het type van de aangepaste clientreferentieklasse te retourneren die is gemaakt met het configuratie-element.
Overschrijf de CreateBehavior methode. De methode is verantwoordelijk voor het maken en retourneren van een exemplaar van de aangepaste referentieklasse op basis van de instellingen die zijn geladen vanuit het configuratiebestand. Roep de basismethode ApplyConfiguration(ClientCredentials) van deze methode aan om de door het systeem geleverde referentie-instellingen op te halen die zijn geladen in uw exemplaar van aangepaste clientreferenties.
Optioneel. Als u extra eigenschappen hebt toegevoegd in stap 2, moet u de Properties eigenschap overschrijven om uw aanvullende configuratie-instellingen te registreren voor het configuratieframework om deze te herkennen. Combineer uw eigenschappen met de eigenschappen van de basisklasse zodat de door het systeem geleverde instellingen kunnen worden geconfigureerd via dit configuratie-element voor aangepaste clientreferenties.
public class MyClientCredentialsConfigHandler : ClientCredentialsElement { ConfigurationPropertyCollection properties; public override Type BehaviorType { get { return typeof(MyClientCredentials); } } public string CreditCardNumber { get { return (string)base["creditCardNumber"]; } set { if (String.IsNullOrEmpty(value)) { value = String.Empty; } base["creditCardNumber"] = value; } } protected override ConfigurationPropertyCollection Properties { get { if (this.properties == null) { ConfigurationPropertyCollection properties = base.Properties; properties.Add(new ConfigurationProperty( "creditCardNumber", typeof(System.String), string.Empty, null, new StringValidator(0, 32, null), ConfigurationPropertyOptions.None)); this.properties = properties; } return this.properties; } } protected override object CreateBehavior() { MyClientCredentials creds = new MyClientCredentials(); creds.CreditCardNumber = CreditCardNumber; base.ApplyConfiguration(creds); return creds; } }
Public Class MyClientCredentialsConfigHandler Inherits ClientCredentialsElement Private propertiesValue As ConfigurationPropertyCollection Public Overrides ReadOnly Property BehaviorType() As Type Get Return GetType(MyClientCredentials) End Get End Property Public Property CreditCardNumber() As String Get Return CStr(MyBase.Item("creditCardNumber")) End Get Set If String.IsNullOrEmpty(value) Then value = String.Empty End If MyBase.Item("creditCardNumber") = value End Set End Property Protected Overrides ReadOnly Property Properties() As ConfigurationPropertyCollection Get If Me.propertiesValue Is Nothing Then Dim myProperties As ConfigurationPropertyCollection = MyBase.Properties myProperties.Add(New ConfigurationProperty( _ "creditCardNumber", _ GetType(System.String), _ String.Empty, _ Nothing, _ New StringValidator(0, 32, Nothing), _ ConfigurationPropertyOptions.None)) Me.propertiesValue = myProperties End If Return Me.propertiesValue End Get End Property Protected Overrides Function CreateBehavior() As Object Dim creds As New MyClientCredentials() creds.CreditCardNumber = Me.CreditCardNumber MyBase.ApplyConfiguration(creds) Return creds End Function End Class
Zodra u de configuratiehandlerklasse hebt, kan deze worden geïntegreerd in het WCF-configuratieframework. Hierdoor kunnen de aangepaste clientreferenties worden gebruikt in de gedragselementen van het clienteindpunt, zoals wordt weergegeven in de volgende procedure.
Een configuratiehandler voor aangepaste clientreferenties registreren en gebruiken in de toepassingsconfiguratie
Voeg een
<extensions>
element en een<behaviorExtensions>
element toe aan het configuratiebestand.Voeg een
<add>
element toe aan het<behaviorExtensions>
element en stel hetname
kenmerk in op een geschikte waarde.Stel het
type
kenmerk in op de volledig gekwalificeerde typenaam. Neem ook de assemblynaam en andere assemblykenmerken op.<system.serviceModel> <extensions> <behaviorExtensions> <add name="myClientCredentials" type="Microsoft.ServiceModel.Samples.MyClientCredentialsConfigHandler, CustomCredentials, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" /> </behaviorExtensions> </extensions> </system.serviceModel>
Nadat u de configuratie-handler hebt geregistreerd, kan het element voor aangepaste referenties in hetzelfde configuratiebestand worden gebruikt in plaats van het door het systeem opgegeven
<clientCredentials>
element. U kunt zowel de door het systeem geleverde eigenschappen als eventuele nieuwe eigenschappen gebruiken die u hebt toegevoegd aan de implementatie van uw configuratiehandler. In het volgende voorbeeld wordt de waarde van een aangepaste eigenschap ingesteld met behulp van hetcreditCardNumber
kenmerk.<behaviors> <endpointBehaviors> <behavior name="myClientCredentialsBehavior"> <myClientCredentials creditCardNumber="123-123-123"/> </behavior> </endpointBehaviors> </behaviors>
Aangepaste servicereferenties implementeren
Definieer een nieuwe klasse die is afgeleid van ServiceCredentials.
Optioneel. Voeg nieuwe eigenschappen toe om API's op te geven voor nieuwe referentiewaarden die worden toegevoegd. Als u geen nieuwe referentiewaarden toevoegt, slaat u deze stap over. In het volgende voorbeeld wordt een
AdditionalCertificate
eigenschap toegevoegd.Overschrijf de CreateSecurityTokenManager methode. Deze methode wordt automatisch aangeroepen door de WCF-infrastructuur wanneer de aangepaste clientreferentie wordt gebruikt. De methode is verantwoordelijk voor het maken en retourneren van een exemplaar van een implementatie van de SecurityTokenManager klasse (beschreven in de volgende procedure).
Optioneel. Overschrijf de CloneCore methode. Dit is alleen vereist als u nieuwe eigenschappen of interne velden toevoegt aan de implementatie van aangepaste clientreferenties.
public class MyServiceCredentials : ServiceCredentials { X509Certificate2 additionalCertificate; public MyServiceCredentials() { } protected MyServiceCredentials(MyServiceCredentials other) : base(other) { this.additionalCertificate = other.additionalCertificate; } public X509Certificate2 AdditionalCertificate { get { return this.additionalCertificate; } set { if (value == null) { throw new ArgumentNullException("value"); } this.additionalCertificate = value; } } public override SecurityTokenManager CreateSecurityTokenManager() { return base.CreateSecurityTokenManager(); } protected override ServiceCredentials CloneCore() { return new MyServiceCredentials(this); } }
Public Class MyServiceCredentials Inherits ServiceCredentials Private additionalCertificateValue As X509Certificate2 Public Sub New() End Sub Protected Sub New(ByVal other As MyServiceCredentials) MyBase.New(other) Me.additionalCertificate = other.additionalCertificate End Sub Public Property AdditionalCertificate() As X509Certificate2 Get Return Me.additionalCertificateValue End Get Set If value Is Nothing Then Throw New ArgumentNullException("value") End If Me.additionalCertificateValue = value End Set End Property Public Overrides Function CreateSecurityTokenManager() As SecurityTokenManager Return MyBase.CreateSecurityTokenManager() End Function Protected Overrides Function CloneCore() As ServiceCredentials Return New MyServiceCredentials(Me) End Function End Class
Een aangepast servicebeveiligingstokenbeheer implementeren
Definieer een nieuwe klasse die is afgeleid van de ServiceCredentialsSecurityTokenManager klasse.
Optioneel. Overschrijf de CreateSecurityTokenProvider methode als er een aangepaste SecurityTokenProvider implementatie moet worden gemaakt. Zie How to: Create a Custom Security Token Provider (Een aangepaste beveiligingstokenprovider maken) voor meer informatie over aangepaste beveiligingstokenproviders.
Optioneel. Overschrijf de CreateSecurityTokenAuthenticator methode als er een aangepaste SecurityTokenAuthenticator implementatie moet worden gemaakt. Zie How to: Create a Custom Security Token Authenticator topic voor meer informatie over aangepaste beveiligingstoken authenticators.
Optioneel. Overschrijf de CreateSecurityTokenSerializer(SecurityTokenVersion) methode als er een aangepaste SecurityTokenSerializer moet worden gemaakt. Zie Een aangepast token maken voor meer informatie over aangepaste beveiligingstokens en serializers voor aangepaste beveiligingstokens.
internal class MyServiceCredentialsSecurityTokenManager : ServiceCredentialsSecurityTokenManager { MyServiceCredentials credentials; public MyServiceCredentialsSecurityTokenManager(MyServiceCredentials credentials) : base(credentials) { this.credentials = credentials; } public override SecurityTokenProvider CreateSecurityTokenProvider(SecurityTokenRequirement tokenRequirement) { // Return your implementation of SecurityTokenProvider, if required. // This implementation delegates to the base class. return base.CreateSecurityTokenProvider(tokenRequirement); } public override SecurityTokenAuthenticator CreateSecurityTokenAuthenticator(SecurityTokenRequirement tokenRequirement, out SecurityTokenResolver outOfBandTokenResolver) { // Return your implementation of SecurityTokenProvider, if required. // This implementation delegates to the base class. return base.CreateSecurityTokenAuthenticator(tokenRequirement, out outOfBandTokenResolver); } public override SecurityTokenSerializer CreateSecurityTokenSerializer(SecurityTokenVersion version) { // Return your implementation of SecurityTokenProvider, if required. // This implementation delegates to the base class. return base.CreateSecurityTokenSerializer(version); } }
Friend Class MyServiceCredentialsSecurityTokenManager Inherits ServiceCredentialsSecurityTokenManager Private credentials As MyServiceCredentials Public Sub New(ByVal credentials As MyServiceCredentials) MyBase.New(credentials) Me.credentials = credentials End Sub Public Overrides Function CreateSecurityTokenProvider(ByVal tokenRequirement As SecurityTokenRequirement) _ As SecurityTokenProvider ' Return your implementation of SecurityTokenProvider, if required. ' This implementation delegates to the base class. Return MyBase.CreateSecurityTokenProvider(tokenRequirement) End Function Public Overrides Function CreateSecurityTokenAuthenticator( _ ByVal tokenRequirement As SecurityTokenRequirement, _ ByRef outOfBandTokenResolver As SecurityTokenResolver) _ As SecurityTokenAuthenticator ' Return your implementation of SecurityTokenProvider, if required. ' This implementation delegates to the base class. Return MyBase.CreateSecurityTokenAuthenticator(tokenRequirement, outOfBandTokenResolver) End Function Public Overrides Function CreateSecurityTokenSerializer(ByVal version As SecurityTokenVersion) _ As SecurityTokenSerializer ' Return your implementation of SecurityTokenProvider, if required. ' This implementation delegates to the base class. Return MyBase.CreateSecurityTokenSerializer(version) End Function End Class
Aangepaste servicereferenties gebruiken vanuit toepassingscode
Maak een instantie van de ServiceHost.
Verwijder het gedrag van de door het systeem geleverde servicereferenties uit de Behaviors verzameling.
Maak een nieuw exemplaar van de klasse referenties van de aangepaste service en voeg deze toe aan de Behaviors verzameling.
// Create a service host with a service type. ServiceHost serviceHost = new ServiceHost(typeof(Service)); // Remove the default ServiceCredentials behavior. serviceHost.Description.Behaviors.Remove<ServiceCredentials>(); // Add a custom service credentials instance to the collection. serviceHost.Description.Behaviors.Add(new MyServiceCredentials());
' Create a service host with a service type. Dim serviceHost As New ServiceHost(GetType(Service)) ' Remove the default ServiceCredentials behavior. serviceHost.Description.Behaviors.Remove(Of ServiceCredentials)() ' Add a custom service credentials instance to the collection. serviceHost.Description.Behaviors.Add(New MyServiceCredentials())
Voeg ondersteuning toe voor configuratie met behulp van de stappen die eerder in de procedures 'To create a configuration handler for custom client credentials
' en 'To register and use a custom client credentials configuration handler in the application configuration
' zijn beschreven. Het enige verschil is het gebruik van de ServiceCredentialsElement klasse in plaats van de ClientCredentialsElement klasse als basisklasse voor de configuratiehandler. Het referentie-element van de aangepaste service kan vervolgens worden gebruikt waar het door het systeem geleverde <serviceCredentials>
element wordt gebruikt.