Návod: Vytvoření vlastního klienta a pověření služby
Toto téma ukazuje, jak implementovat vlastní přihlašovací údaje klienta a služby a jak používat vlastní přihlašovací údaje z kódu aplikace.
Třídy rozšiřitelnosti přihlašovacích údajů
ServiceCredentials Třídy ClientCredentials jsou hlavními vstupními body rozšiřitelnosti zabezpečení WCF (Windows Communication Foundation). Tyto třídy přihlašovacích údajů poskytují rozhraní API, která umožňují kódu aplikace nastavit informace o přihlašovacích údajích a převést typy přihlašovacích údajů na tokeny zabezpečení. (Tokeny zabezpečení jsou formulář používaný k přenosu informací o přihlašovacích údajích uvnitř zpráv SOAP.) Odpovědnosti těchto tříd přihlašovacích údajů je možné rozdělit do dvou oblastí:
Zadejte rozhraní API pro aplikace k nastavení informací o přihlašovacích údajích.
Proveďte jako továrnu pro SecurityTokenManager implementace.
Výchozí implementace poskytované v WCF podporují systémové typy přihlašovacích údajů a vytvářejí správce tokenů zabezpečení, který dokáže tyto typy přihlašovacích údajů zpracovat.
Důvody k přizpůsobení
Přizpůsobení tříd přihlašovacích údajů klienta nebo služby má několik důvodů. Především je požadavek na změnu výchozího chování zabezpečení WCF, pokud jde o zpracování typů přihlašovacích údajů zadaných systémem, zejména z následujících důvodů:
Změny, které nejsou možné použít jiné body rozšiřitelnosti.
Přidání nových typů přihlašovacích údajů
Přidání nových vlastních typů tokenů zabezpečení
Toto téma popisuje, jak implementovat vlastní přihlašovací údaje klienta a služby a jak je používat z kódu aplikace.
První v řadě
Vytvoření vlastní třídy přihlašovacích údajů je pouze prvním krokem, protože důvodem pro přizpůsobení přihlašovacích údajů je změna chování WCF týkající se zřizování přihlašovacích údajů, serializace tokenu zabezpečení nebo ověřování. Další témata v této části popisují, jak vytvořit vlastní serializátory a ověřovací objekty. V tomto ohledu je vytvoření vlastní třídy přihlašovacích údajů prvním tématem v řadě. Následné akce (vytváření vlastních serializátorů a ověřovacích objektů) je možné provést až po vytvoření vlastních přihlašovacích údajů. Mezi další témata, která vycházejí z tohoto tématu, patří:
Postupy: Vytvoření vlastního zprostředkovatele tokenů zabezpečení
Postupy: Vytvoření vlastních ověřovacích dat tokenu zabezpečení
Procedury
Implementace vlastních přihlašovacích údajů klienta
Definujte novou třídu odvozenou ClientCredentials z třídy.
Nepovinné. Přidejte nové metody nebo vlastnosti pro nové typy přihlašovacích údajů. Pokud nepřidáte nové typy přihlašovacích údajů, tento krok přeskočte. Následující příklad přidá
CreditCardNumber
vlastnost.Přepište metodu CreateSecurityTokenManager . Tato metoda je automaticky volána infrastrukturou zabezpečení WCF při použití vlastních přihlašovacích údajů klienta. Tato metoda zodpovídá za vytvoření a vrácení instance implementace SecurityTokenManager třídy.
Důležité
Je důležité si uvědomit, že CreateSecurityTokenManager metoda je přepsána k vytvoření vlastního správce tokenů zabezpečení. Správce tokenů zabezpečení, odvozený z ClientCredentialsSecurityTokenManager, musí vrátit vlastního zprostředkovatele tokenu zabezpečení odvozeného od SecurityTokenProvider, k vytvoření skutečného tokenu zabezpečení. Pokud tento vzor pro vytváření tokenů zabezpečení nesplníte, může aplikace při ukládání objektů do mezipaměti fungovat nesprávně ChannelFactory (což je výchozí chování pro proxy klientů WCF), což může způsobit útok na zvýšení oprávnění. Vlastní objekt přihlašovacích údajů je uložen v mezipaměti jako součást objektu ChannelFactory. Vlastní SecurityTokenManager se však vytvoří při každém vyvolání, což zmírní bezpečnostní hrozbu, pokud je logika vytvoření tokenu umístěna SecurityTokenManagerdo .
Přepište metodu CloneCore .
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
Implementace vlastního správce tokenů zabezpečení klienta
Definujte novou třídu odvozenou z ClientCredentialsSecurityTokenManager.
Nepovinné. Přepište metodu CreateSecurityTokenProvider(SecurityTokenRequirement) , pokud je nutné vytvořit vlastní SecurityTokenProvider implementaci. Další informace o vlastních poskytovateli tokenů zabezpečení naleznete v tématu Postupy: Vytvoření vlastního zprostředkovatele tokenů zabezpečení.
Nepovinné. Přepište metodu CreateSecurityTokenAuthenticator(SecurityTokenRequirement, SecurityTokenResolver) , pokud je nutné vytvořit vlastní SecurityTokenAuthenticator implementaci. Další informace o vlastních ověřovacích tokenech zabezpečení naleznete v tématu Postupy: Vytvoření vlastního ověřovacího tokenu zabezpečení.
Nepovinné. Přepište metodu CreateSecurityTokenSerializer , pokud je nutné vytvořit vlastní SecurityTokenSerializer . Další informace o vlastních tokenech zabezpečení a vlastních serializátorech tokenů zabezpečení naleznete v tématu Postupy: Vytvoření vlastního tokenu.
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
Použití vlastních přihlašovacích údajů klienta z kódu aplikace
Buď vytvořte instanci vygenerovaného klienta, který představuje rozhraní služby, nebo vytvořte instanci ChannelFactory odkazující na službu, se kterou chcete komunikovat.
Odeberte ze kolekce chování Behaviors přihlašovacích údajů klienta poskytnutého systémem, ke kterému je možné přistupovat prostřednictvím Endpoint vlastnosti.
Vytvořte novou instanci vlastní třídy přihlašovacích údajů klienta a přidejte ji do Behaviors kolekce, ke které lze přistupovat prostřednictvím Endpoint vlastnosti.
// 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())
Předchozí postup ukazuje, jak používat přihlašovací údaje klienta z kódu aplikace. Přihlašovací údaje WCF je také možné nakonfigurovat pomocí konfiguračního souboru aplikace. Použití konfigurace aplikace je často vhodnější než pevné kódování, protože umožňuje úpravy parametrů aplikace, aniž by bylo nutné upravovat zdroj, rekompilování a opětovné nasazení.
Další postup popisuje, jak poskytnout podporu konfigurace vlastních přihlašovacích údajů.
Vytvoření obslužné rutiny konfigurace pro vlastní přihlašovací údaje klienta
Definujte novou třídu odvozenou z ClientCredentialsElement.
Nepovinné. Přidejte vlastnosti pro všechny další parametry konfigurace, které chcete zveřejnit prostřednictvím konfigurace aplikace. Následující příklad přidá jednu vlastnost s názvem
CreditCardNumber
.BehaviorType Přepište vlastnost tak, aby vrátila typ vlastní třídy přihlašovacích údajů klienta vytvořené pomocí elementu konfigurace.
Přepište metodu CreateBehavior . Metoda zodpovídá za vytvoření a vrácení instance vlastní třídy přihlašovacích údajů na základě nastavení načteného z konfiguračního souboru. Voláním základní ApplyConfiguration(ClientCredentials) metody z této metody načtěte nastavení přihlašovacích údajů zadaných systémem načtených do instance vlastních přihlašovacích údajů klienta.
Nepovinné. Pokud jste v kroku 2 přidali další vlastnosti, musíte tuto vlastnost přepsat Properties , abyste mohli zaregistrovat další nastavení konfigurace pro konfigurační architekturu, abyste je rozpoznali. Zkombinujte své vlastnosti s vlastnostmi základní třídy, abyste umožnili konfiguraci nastavení poskytovaného systémem prostřednictvím tohoto konfiguračního prvku vlastních přihlašovacích údajů klienta.
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
Jakmile máte třídu obslužné rutiny konfigurace, lze ji integrovat do konfigurační architektury WCF. To umožňuje použití vlastních přihlašovacích údajů klienta v elementech chování koncového bodu klienta, jak je znázorněno v dalším postupu.
Registrace a použití obslužné rutiny konfigurace vlastních přihlašovacích údajů klienta v konfiguraci aplikace
<extensions>
Přidejte element a<behaviorExtensions>
element do konfiguračního souboru.<add>
Přidejte prvek do elementu<behaviorExtensions>
a nastavtename
atribut na odpovídající hodnotu.type
Nastavte atribut na plně kvalifikovaný název typu. Zahrňte také název sestavení a další atributy sestavení.<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>
Po registraci obslužné rutiny konfigurace lze vlastní prvek přihlašovacích údajů použít uvnitř stejného konfiguračního souboru místo elementu poskytnutého
<clientCredentials>
systémem. Můžete použít vlastnosti poskytované systémem i všechny nové vlastnosti, které jste přidali do implementace obslužné rutiny konfigurace. Následující příklad nastaví hodnotu vlastní vlastnosti pomocí atributucreditCardNumber
.<behaviors> <endpointBehaviors> <behavior name="myClientCredentialsBehavior"> <myClientCredentials creditCardNumber="123-123-123"/> </behavior> </endpointBehaviors> </behaviors>
Implementace vlastních přihlašovacích údajů služby
Definujte novou třídu odvozenou z ServiceCredentials.
Nepovinné. Přidejte nové vlastnosti, které poskytují rozhraní API pro nové přidané hodnoty přihlašovacích údajů. Pokud nepřidáte nové hodnoty přihlašovacích údajů, tento krok přeskočte. Následující příklad přidá
AdditionalCertificate
vlastnost.Přepište metodu CreateSecurityTokenManager . Tato metoda je automaticky volána infrastrukturou WCF při použití vlastních přihlašovacích údajů klienta. Metoda je zodpovědná za vytvoření a vrácení instance implementace SecurityTokenManager třídy (popsané v dalším postupu).
Nepovinné. Přepište metodu CloneCore . To se vyžaduje jenom v případě, že do implementace vlastních přihlašovacích údajů klienta přidáte nové vlastnosti nebo interní pole.
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
Implementace vlastního správce tokenů zabezpečení služby
Definujte novou třídu odvozenou ServiceCredentialsSecurityTokenManager z třídy.
Nepovinné. Přepište metodu CreateSecurityTokenProvider , pokud je nutné vytvořit vlastní SecurityTokenProvider implementaci. Další informace o vlastních poskytovateli tokenů zabezpečení naleznete v tématu Postupy: Vytvoření vlastního zprostředkovatele tokenů zabezpečení.
Nepovinné. Přepište metodu CreateSecurityTokenAuthenticator , pokud je nutné vytvořit vlastní SecurityTokenAuthenticator implementaci. Další informace o vlastních ověřovacích tokenech zabezpečení naleznete v tématu Postupy: Vytvoření vlastního tématu ověřovacího tokenu zabezpečení.
Nepovinné. Přepište metodu CreateSecurityTokenSerializer(SecurityTokenVersion) , pokud je nutné vytvořit vlastní SecurityTokenSerializer . Další informace o vlastních tokenech zabezpečení a vlastních serializátorech tokenů zabezpečení naleznete v tématu Postupy: Vytvoření vlastního tokenu.
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
Použití vlastních přihlašovacích údajů služby z kódu aplikace
Vytvořte instanci ServiceHost.
Odeberte chování přihlašovacích údajů služby poskytované systémem z Behaviors kolekce.
Vytvořte novou instanci třídy přihlašovacích údajů vlastní služby a přidejte ji do Behaviors kolekce.
// 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())
Přidání podpory konfigurace pomocí kroků popsaných výše v postupech "To create a configuration handler for custom client credentials
" a "To register and use a custom client credentials configuration handler in the application configuration
" Jediným rozdílem je použití ServiceCredentialsElement třídy místo ClientCredentialsElement třídy jako základní třídy pro obslužnou rutinu konfigurace. Prvek přihlašovacích údajů vlastní služby se pak dá použít všude, kde se používá systémový <serviceCredentials>
prvek.
Viz také
- ClientCredentials
- ServiceCredentials
- SecurityCredentialsManager
- SecurityTokenManager
- ClientCredentialsElement
- ServiceCredentialsElement
- Postupy: Vytvoření vlastního zprostředkovatele tokenů zabezpečení
- Postupy: Vytvoření vlastních ověřovacích dat tokenu zabezpečení
- Postupy: Vytvoření vlastního tokenu