Bagikan melalui


Panduan: Membuat Mandat Klien dan Layanan Kustom

Topik ini menunjukkan cara menerapkan mandat klien dan layanan kustom dan cara menggunakan mandat kustom dari kode aplikasi.

Kelas Ekstensibilitas Mandat

Kelas ClientCredentials dan ServiceCredentials adalah titik masuk utama ke ekstensibilitas keamanan Windows Communication Foundation (WCF). Kelas mandat ini menyediakan API yang memungkinkan kode aplikasi mengatur informasi mandat dan untuk mengonversi jenis mandat menjadi token keamanan. (Token keamanan adalah formulir yang digunakan untuk mengirimkan informasi mandat di dalam pesan SOAP.) Tanggung jawab kelas mandat ini dapat dibagi menjadi dua area:

  • Berikan API bagi aplikasi untuk mengatur informasi mandat.

  • Lakukan sebagai pabrik untuk implementasi SecurityTokenManager.

Implementasi default yang disediakan dalam WCF mendukung jenis mandat yang disediakan sistem dan membuat manajer token keamanan yang mampu menangani jenis mandat tersebut.

Alasan untuk Menyesuaikan

Ada beberapa alasan untuk menyesuaikan kelas mandat klien atau layanan. Yang terpenting adalah persyaratan untuk mengubah perilaku keamanan WCF default sehubungan dengan penanganan jenis mandat yang disediakan sistem, terutama karena alasan berikut:

  • Perubahan yang tidak dimungkinkan menggunakan titik ekstensibilitas lainnya.

  • Menambahkan jenis mandat baru.

  • Menambahkan jenis token keamanan kustom baru.

Topik ini menjelaskan cara menerapkan mandat klien dan layanan kustom dan cara menggunakan mandat kustom dari kode aplikasi.

Pertama dalam Seri

Membuat kelas mandat kustom hanyalah langkah pertama, karena alasan untuk menyesuaikan mndat adalah untuk mengubah perilaku WCF mengenai penyediaan mandat, serialisasi token keamanan, atau autentikasi. Topik lain di bagian ini menjelaskan cara membuat serializer dan pengautentikasi kustom. Dalam hal ini, membuat kelas mandat kustom adalah topik pertama dalam seri ini. Tindakan berikutnya (membuat serializer dan pengautentikasi kustom) hanya dapat dilakukan setelah membuat mandat kustom. Topik tambahan yang dibangun berdasarkan topik ini meliputi:

Prosedur

Untuk menerapkan mandat klien kustom

  1. Tentukan kelas baru turunan dari kelas ClientCredentials.

  2. Opsional. Tambahkan metode atau properti baru untuk jenis mandat baru. Jika Anda tidak menambahkan jenis mandat baru, lewati langkah ini. Contoh berikut menambahkan properti CreditCardNumber.

  3. Ambil alih metode CreateSecurityTokenManager. Metode ini secara otomatis dipanggil oleh infrastruktur keamanan WCF saat mandat klien kustom digunakan. Metode ini bertanggung jawab untuk membuat dan mengembalikan instans implementasi kelas SecurityTokenManager.

    Penting

    Penting untuk dicatat bahwa metode CreateSecurityTokenManager ini ditimpa untuk membuat manajer token keamanan kustom. Manajer token keamanan, yang berasal dari ClientCredentialsSecurityTokenManager, harus mengembalikan penyedia token keamanan kustom, yang berasal dari SecurityTokenProvider, untuk membuat token keamanan yang sebenarnya. Jika Anda tidak mengikuti pola ini untuk membuat token keamanan, aplikasi Anda mungkin berfungsi dengan salah saat objek ChannelFactory di-cache (yang merupakan perilaku default untuk proksi klien WCF), berpotensi mengakibatkan peningkatan serangan hak istimewa. Objek mandat kustom di-cache sebagai bagian dari ChannelFactory. Namun, SecurityTokenManager kustom dibuat pada setiap pemanggilan, yang mengurangi ancaman keamanan selama logika pembuatan token ditempatkan di SecurityTokenManager.

  4. Ambil alih metode 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
    

Untuk menerapkan manajer token keamanan klien kustom

  1. Tentukan kelas baru turunan dari ClientCredentialsSecurityTokenManager.

  2. Opsional. Ambil alih metode CreateSecurityTokenProvider(SecurityTokenRequirement) jika implementasi SecurityTokenProvider kustom harus dibuat. Untuk informasi selengkapnya tentang penyedia token keamanan kustom, lihat Cara: Membuat Penyedia Token Keamanan Kustom.

  3. Opsional. Ambil alih metode CreateSecurityTokenAuthenticator(SecurityTokenRequirement, SecurityTokenResolver) jika implementasi SecurityTokenAuthenticator kustom harus dibuat. Untuk informasi selengkapnya tentang pengautentikasi token keamanan khusus, lihat Cara: Membuat Pengautentikasi Token Keamanan Khusus.

  4. Opsional. Ambil alih metode CreateSecurityTokenSerializer jika SecurityTokenSerializer kustom harus dibuat. Untuk informasi selengkapnya tentang token keamanan dan serializer token keamanan kustom, lihat Cara: Membuat Penyedia Token Kustom.

    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
    

Untuk menggunakan mandat klien kustom dari kode aplikasi

  1. Buat instans klien yang dihasilkan yang mewakili antarmuka layanan, atau buat instans ChannelFactory yang menunjuk ke layanan yang ingin Anda komunikasikan.

  2. Hapus perilaku mandat klien yang disediakan sistem dari koleksi Behaviors, yang dapat diakses melalui properti Endpoint.

  3. Buat instans baru kelas mandat klien kustom dan tambahkan ke koleksi Behaviors, yang dapat diakses melalui properti Endpoint.

    // 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())
    

Prosedur sebelumnya menunjukkan cara menggunakan mandat klien dari kode aplikasi. Mandat WCF juga dapat dikonfigurasi menggunakan file konfigurasi aplikasi. Menggunakan konfigurasi aplikasi sering lebih disukai daripada pengodean permanen karena memungkinkan modifikasi parameter aplikasi tanpa harus memodifikasi sumber, kompilasi ulang, dan penyebaran ulang.

Prosedur berikutnya menjelaskan cara memberikan dukungan untuk konfigurasi mandat kustom.

Membuat handler konfigurasi untuk mandat klien kustom

  1. Tentukan kelas baru turunan dari ClientCredentialsElement.

  2. Opsional. Tambahkan properti untuk semua parameter konfigurasi tambahan yang ingin Anda ekspos melalui konfigurasi aplikasi. Contoh di bawah ini menambahkan satu properti bernama CreditCardNumber.

  3. Ambil alih properti BehaviorType untuk mengembalikan jenis kelas mandat klien kustom yang dibuat dengan elemen konfigurasi.

  4. Ambil alih metode CreateBehavior. Metode ini bertanggung jawab untuk membuat dan mengembalikan instans kelas mandat kustom berdasarkan pengaturan yang dimuat dari file konfigurasi. Panggil metode ApplyConfiguration(ClientCredentials) dasar dari metode ini untuk mengambil pengaturan mandat yang disediakan sistem yang dimuat ke dalam instans mandat klien kustom Anda.

  5. Opsional. Jika Anda menambahkan properti tambahan di langkah 2, Anda perlu mengambil alih properti Properties untuk mendaftarkan pengaturan konfigurasi tambahan Anda agar kerangka kerja konfigurasi mengenalinya. Gabungkan properti Anda dengan properti kelas dasar untuk memungkinkan pengaturan yang disediakan sistem dikonfigurasi melalui elemen konfigurasi mandat klien kustom ini.

    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
    

Setelah Anda memiliki kelas handler konfigurasi, ini dapat diintegrasikan ke dalam kerangka kerja konfigurasi WCF. Ini memungkinkan mandat klien kustom digunakan dalam elemen perilaku titik akhir klien, seperti yang ditunjukkan pada prosedur berikutnya.

Untuk mendaftar dan menggunakan handler konfigurasi mandat klien kustom dalam konfigurasi aplikasi

  1. Tambahkan elemen <extensions> dan elemen <behaviorExtensions> ke file konfigurasi.

  2. Tambahkan elemen <add> ke elemen <behaviorExtensions> dan atur atribut name ke nilai yang sesuai.

  3. Atur atribut type ke nama jenis yang sepenuhnya memenuhi syarat. Sertakan juga nama rakitan dan atribut rakitan lainnya.

    <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>
    
  4. Setelah mendaftarkan handler konfigurasi Anda, elemen mandat kustom dapat digunakan di dalam file konfigurasi yang sama alih-alih elemen <clientCredentials> yang disediakan sistem. Anda dapat menggunakan properti yang disediakan sistem dan properti baru apa pun yang telah Anda tambahkan ke implementasi handler konfigurasi. Contoh berikut menetapkan nilai properti kustom menggunakan atribut creditCardNumber.

    <behaviors>
      <endpointBehaviors>
        <behavior name="myClientCredentialsBehavior">
          <myClientCredentials creditCardNumber="123-123-123"/>
        </behavior>
      </endpointBehaviors>
    </behaviors>
    

Untuk menerapkan mandat layanan kustom

  1. Tentukan kelas baru turunan dari ServiceCredentials.

  2. Opsional. Tambahkan properti baru untuk menyediakan API untuk nilai mandat baru yang sedang ditambahkan. Jika Anda tidak menambahkan nilai mandat baru, lewati langkah ini. Contoh berikut menambahkan properti AdditionalCertificate.

  3. Ambil alih metode CreateSecurityTokenManager. Metode ini secara otomatis dipanggil oleh infrastruktur WCF saat mandat klien kustom digunakan. Metode ini bertanggung jawab untuk membuat dan mengembalikan instans implementasi kelas SecurityTokenManager (dijelaskan dalam prosedur berikutnya).

  4. Opsional. Ambil alih metode CloneCore. Ini diperlukan hanya jika menambahkan properti baru atau bidang internal ke implementasi mandat klien kustom.

    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
    

Untuk menerapkan manajer token keamanan layanan kustom

  1. Tentukan kelas baru turunan dari kelas ServiceCredentialsSecurityTokenManager.

  2. Opsional. Ambil alih metode CreateSecurityTokenProvider jika implementasi SecurityTokenProvider kustom harus dibuat. Untuk informasi selengkapnya tentang penyedia token keamanan kustom, lihat Cara: Membuat Penyedia Token Keamanan Kustom.

  3. Opsional. Ambil alih metode CreateSecurityTokenAuthenticator jika implementasi SecurityTokenAuthenticator kustom harus dibuat. Untuk informasi selengkapnya tentang pengautentikasi token keamanan khusus, lihat topik Cara: Membuat Pengautentikasi Token Keamanan Khusus.

  4. Opsional. Ambil alih metode CreateSecurityTokenSerializer(SecurityTokenVersion) jika SecurityTokenSerializer kustom harus dibuat. Untuk informasi selengkapnya tentang token keamanan dan serializer token keamanan kustom, lihat Cara: Membuat Penyedia Token Kustom.

    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
    

Untuk menggunakan mandat layanan kustom dari kode aplikasi

  1. Buat instans ServiceHost.

  2. Hapus perilaku mandat layanan yang disediakan sistem dari koleksi Behaviors.

  3. Buat instans baru kelas mandat layanan kustom dan tambahkan ke koleksi Behaviors.

    // 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())
    

Tambahkan dukungan untuk konfigurasi menggunakan langkah-langkah yang dijelaskan sebelumnya dalam prosedur "To create a configuration handler for custom client credentials" dan "To register and use a custom client credentials configuration handler in the application configuration." Satu-satunya perbedaan adalah menggunakan kelas ServiceCredentialsElement alih-alih kelas ClientCredentialsElement sebagai kelas dasar untuk handler konfigurasi. Elemen mandat layanan kustom kemudian dapat digunakan di mana pun elemen <serviceCredentials> yang disediakan sistem digunakan.

Lihat juga