Bahasa

Pemrograman Keamanan WCF

Topik ini menjelaskan tugas pemrograman dasar yang digunakan untuk membuat aplikasi Windows Communication Foundation (WCF) yang aman. Topik ini hanya mencakup autentikasi, kerahasiaan, dan integritas, yang secara kolektif dikenal sebagai keamanan transfer . Topik ini tidak mencakup otorisasi (kontrol akses ke sumber daya atau layanan); untuk informasi tentang otorisasi, lihat Otorisasi.

Nota

Untuk pengantar konsep keamanan yang berharga, terutama sehubungan dengan WCF, lihat serangkaian pola dan tutorial praktik tentang MSDN pada Skenario , Pola, dan Panduan Implementasi untuk Peningkatan Layanan Web (WSE) 3.0.

Pemrograman keamanan WCF didasarkan pada tiga langkah pengaturan berikut: mode keamanan, jenis kredensial klien, dan nilai kredensial. Anda dapat melakukan langkah-langkah ini baik melalui kode atau konfigurasi.

Mengatur Mode Keamanan

Berikut ini menjelaskan langkah-langkah umum untuk pemrograman dengan mode keamanan di WCF:

  1. Pilih salah satu pengikatan yang telah ditentukan sebelumnya yang sesuai dengan persyaratan aplikasi Anda. Untuk daftar pilihan pengikatan, lihat System-Provided Pengikatan. Secara default, hampir setiap pengikatan mengaktifkan keamanan. Satu pengecualian adalah kelas BasicHttpBinding (menggunakan konfigurasi, basicHttpBinding<>).

    Pengikatan yang Anda pilih menentukan transportasi. Misalnya, WSHttpBinding menggunakan HTTP sebagai transportasi; NetTcpBinding menggunakan TCP.

  2. Pilih salah satu mode keamanan untuk pengikatan. Perhatikan bahwa pengikatan yang Anda pilih menentukan pilihan mode yang tersedia. Misalnya, WSDualHttpBinding tidak mengizinkan keamanan transportasi (ini bukan pilihan). Demikian pula, baik MsmqIntegrationBinding maupun NetNamedPipeBinding tidak mengizinkan keamanan pesan.

    Anda memiliki tiga pilihan:

    1. Transport

      Keamanan transportasi tergantung pada mekanisme pengikatan yang telah Anda pilih. Misalnya, jika Anda menggunakan WSHttpBinding maka mekanisme keamanannya adalah Secure Sockets Layer (SSL) (juga mekanisme untuk protokol HTTPS). Secara umum, keuntungan utama dari keamanan transportasi adalah memberikan throughput yang baik apa pun transportasi yang Anda gunakan. Namun, itu memang memiliki dua batasan: Yang pertama adalah mekanisme transportasi menentukan jenis kredensial yang digunakan untuk mengautentikasi pengguna. Ini adalah kelemahan hanya jika layanan perlu beroperasi dengan layanan lain yang menuntut berbagai jenis kredensial. Yang kedua adalah bahwa, karena keamanan tidak diterapkan pada tingkat pesan, keamanan diimplementasikan secara bertahap daripada ujung-ke-ujung. Batasan terakhir ini adalah masalah hanya jika jalur pesan antara klien dan layanan mencakup perantara. Untuk informasi selengkapnya tentang moda transportasi yang akan digunakan, lihat Memilih Moda Transportasi. Untuk informasi selengkapnya tentang menggunakan keamanan transportasi, lihat Gambaran Umum Keamanan Transportasi .

    2. Message

      Keamanan pesan berarti bahwa setiap pesan menyertakan header dan data yang diperlukan untuk menjaga pesan tetap aman. Karena komposisi header bervariasi, Anda dapat menyertakan sejumlah kredensial. Ini menjadi faktor jika Anda beroperasi dengan layanan lain yang memerlukan jenis kredensial tertentu yang tidak dapat diberikan oleh mekanisme transport, atau jika pesan harus digunakan dengan lebih dari satu layanan di mana setiap layanan memerlukan jenis kredensial yang berbeda.

      Untuk informasi selengkapnya, lihat Keamanan Pesan.

    3. TransportWithMessageCredential

      Pilihan ini menggunakan lapisan transportasi untuk mengamankan transfer pesan, sementara setiap pesan menyertakan kredensial kaya yang dibutuhkan layanan lain. Ini menggabungkan keuntungan performa keamanan transportasi dengan keuntungan kredensial yang kaya dari keamanan pesan. Ini tersedia dengan pengikatan berikut: BasicHttpBinding, WSFederationHttpBinding, NetPeerTcpBinding, dan WSHttpBinding.

  3. Jika Anda memutuskan untuk menggunakan keamanan transportasi untuk HTTP (dengan kata lain, HTTPS), Anda juga harus mengonfigurasi host dengan sertifikat SSL dan mengaktifkan SSL pada port. Untuk informasi selengkapnya, lihat Keamanan Transportasi HTTP.

  4. Jika Anda menggunakan WSHttpBinding dan tidak perlu membuat sesi yang aman, atur properti EstablishSecurityContext ke false.

    Sesi aman terjadi ketika klien dan layanan membuat saluran menggunakan kunci simetris (klien dan server menggunakan kunci yang sama untuk lamanya percakapan, hingga dialog ditutup).

Mengatur Jenis Kredensial Klien

Pilih jenis kredensial klien yang sesuai. Untuk informasi selengkapnya, lihat Memilih Jenis Kredensial. Jenis kredensial klien berikut ini tersedia:

  • Windows

  • Certificate

  • Digest

  • Basic

  • UserName

  • NTLM

  • IssuedToken

Bergantung pada cara Anda mengatur mode, Anda harus mengatur jenis kredensial. Misalnya, jika Anda telah memilih wsHttpBinding, dan telah mengatur mode ke "Pesan," maka Anda juga dapat mengatur atribut clientCredentialType elemen Pesan ke salah satu nilai berikut: None, Windows, UserName, Certificate, dan IssuedToken, seperti yang ditunjukkan dalam contoh konfigurasi berikut.

<system.serviceModel>
<bindings>
  <wsHttpBinding>
    <binding name="myBinding">
      <security mode="Message"/>
      <message clientCredentialType="Windows"/>
    </binding>
  </wsHttpBinding>
</bindings>
</system.serviceModel>

Atau dalam kode:

WSHttpBinding b = new WSHttpBinding();
b.Name = "myBinding";
b.Security.Mode = SecurityMode.Message;
b.Security.Message.ClientCredentialType=MessageCredentialType.Windows;
Dim b As New WSHttpBinding()
b.Name = "myBinding"
b.Security.Mode = SecurityMode.Message
b.Security.Message.ClientCredentialType = MessageCredentialType.Windows

Mengatur Nilai Kredensial Layanan

Setelah Anda memilih jenis kredensial klien, Anda harus mengatur kredensial aktual untuk digunakan layanan dan klien. Pada layanan, kredensial diatur dengan menggunakan kelas ServiceCredentials dan dikembalikan melalui properti Credentials dari kelas ServiceHostBase. Pengikatan yang digunakan menyiratkan jenis kredensial layanan, mode keamanan yang dipilih, dan jenis kredensial klien. Kode berikut menetapkan sertifikat untuk kredensial layanan.

// Create the binding for an endpoint.
NetTcpBinding b = new NetTcpBinding();
b.Security.Mode = SecurityMode.Message;

// Create the ServiceHost for a calculator.
Uri baseUri = new Uri("net.tcp://MachineName/tcpBase");
Uri[] baseAddresses = new Uri[] { baseUri };
ServiceHost sh = new ServiceHost(typeof(Calculator), baseAddresses);

// Add an endpoint using the binding and a new address.
Type c = typeof(ICalculator);
sh.AddServiceEndpoint(c, b, "MyEndpoint");

// Set a certificate as the credential for the service.
sh.Credentials.ServiceCertificate.SetCertificate(
    StoreLocation.LocalMachine,
    StoreName.My,
    X509FindType.FindBySubjectName,
    "client.com");
try
{
    sh.Open();
    Console.WriteLine("Listening....");
    Console.ReadLine();
    sh.Close();
}
catch (CommunicationException ce)
{
    Console.WriteLine($"A communication error occurred: {ce.Message}");
    Console.WriteLine();
}
catch (System.Exception exc)
{
    Console.WriteLine($"An unforeseen error occurred: {exc.Message}");
    Console.ReadLine();
}
' Create the binding for an endpoint.
Dim b As New NetTcpBinding()
b.Security.Mode = SecurityMode.Message

' Create the ServiceHost for a calculator.
Dim baseUri As New Uri("net.tcp://MachineName/tcpBase")
Dim baseAddresses() As Uri = {baseUri}
Dim sh As New ServiceHost(GetType(Calculator), baseAddresses)

' Add an endpoint using the binding and a new address.
Dim c As Type = GetType(ICalculator)
sh.AddServiceEndpoint(c, b, "MyEndpoint")

' Set a certificate as the credential for the service.
sh.Credentials.ServiceCertificate.SetCertificate( _
                StoreLocation.LocalMachine, _
                StoreName.My, _
                X509FindType.FindBySubjectName, _
                "contoso.com")
Try
    sh.Open()
    Console.WriteLine("Listening....")
    Console.ReadLine()
    sh.Close()
Catch ce As CommunicationException
    Console.WriteLine("A communication error occurred: {0}", ce.Message)
    Console.WriteLine()
Catch exc As System.Exception
    Console.WriteLine("An unforeseen error occurred: {0}", exc.Message)
    Console.ReadLine()
End Try

Mengatur Nilai Kredensial Klien

Pada klien, atur nilai kredensial klien menggunakan kelas ClientCredentials dan dikembalikan oleh properti ClientCredentials kelas ClientBase<TChannel>. Kode berikut menetapkan sertifikat sebagai kredensial pada klien menggunakan protokol TCP.

// Create a NetTcpBinding and set its security properties. The
// security mode is Message, and the client must be authenticated with
// Windows. Therefore the client must be on the same Windows domain.
NetTcpBinding b = new NetTcpBinding();
b.Security.Mode = SecurityMode.Message;
b.Security.Message.ClientCredentialType = MessageCredentialType.Windows;

// Set a Type variable for use when constructing the endpoint.
Type c = typeof(ICalculator);

// Create a base address for the service.
Uri tcpBaseAddress =
    new Uri("net.tcp://machineName.Domain.Contoso.com:8036/serviceName");
// The base address is in an array of URI objects.
Uri[] baseAddresses = new Uri[] { tcpBaseAddress };
// Create the ServiceHost with type and base addresses.
ServiceHost sh = new ServiceHost(typeof(CalculatorClient), baseAddresses);

// Add an endpoint to the service using the service type and binding.
sh.AddServiceEndpoint(c, b, "");
sh.Open();
string address = sh.Description.Endpoints[0].ListenUri.AbsoluteUri;
Console.WriteLine($"Listening @ {address}");
Console.WriteLine("Press enter to close the service");
Console.ReadLine();
' Create a NetTcpBinding and set its security properties. The
' security mode is Message, and the client must be authenticated with
' Windows. Therefore the client must be on the same Windows domain.
Dim b As New NetTcpBinding()
b.Security.Mode = SecurityMode.Message
b.Security.Message.ClientCredentialType = MessageCredentialType.Windows

' Set a Type variable for use when constructing the endpoint.
Dim c As Type = GetType(ICalculator)

' Create a base address for the service.
Dim tcpBaseAddress As New Uri("net.tcp://machineName.Domain.Contoso.com:8036/serviceName")
' The base address is in an array of URI objects.
Dim baseAddresses() As Uri = {tcpBaseAddress}
' Create the ServiceHost with type and base addresses.
Dim sh As New ServiceHost(GetType(CalculatorClient), baseAddresses)

' Add an endpoint to the service using the service type and binding.
sh.AddServiceEndpoint(c, b, "")
sh.Open()
Dim address As String = sh.Description.Endpoints(0).ListenUri.AbsoluteUri
Console.WriteLine("Listening @ {0}", address)
Console.WriteLine("Press enter to close the service")
Console.ReadLine()

Lihat juga