Bagikan melalui


Memprogram 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.

Catatan

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

Keamanan WCF pemrograman didasarkan pada tiga langkah pengaturan berikut: mode keamanan, jenis mandat klien, dan nilai mandat. 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 Pengikatan yang Disediakan Sistem. 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 mengizinkan keamanan pesan.

    Anda memiliki tiga pilihan:

    1. Transport

      Keamanan transportasi tergantung pada mekanisme pengikatan yang telah dipilih. Misalnya, jika Anda menggunakan WSHttpBinding, mekanisme keamanan 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 mandat yang digunakan untuk mengautentikasi pengguna. Ini merupakan kelemahan hanya jika layanan perlu beroperasi dengan layanan lain yang menuntut berbagai jenis mandat. Yang kedua adalah, karena keamanan tidak diterapkan pada tingkat pesan, keamanan diimplementasikan dengan cara hop-by-hop daripada end-to-end. Batasan terakhir ini merupakan masalah hanya jika jalur pesan antara klien dan layanan mencakup perantara. Untuk mengetahui informasi selengkapnya tentang transportasi mana yang akan digunakan, lihat Memilih Transportasi. Untuk mengetahui informasi selengkapnya tentang menggunakan keamanan transportasi, lihat Ringkasan 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 mandat. Ini menjadi faktor jika Anda beroperasi dengan layanan lain yang menuntut jenis mandat tertentu yang tidak dapat disediakan oleh mekanisme transportasi, atau jika pesan harus digunakan dengan lebih dari satu layanan, yang mana setiap layanan menuntut jenis mandat yang berbeda.

      Untuk mengetahui informasi selengkapnya, lihat Keamanan Pesan.

    3. TransportWithMessageCredential

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

  3. Jika 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 lebih lanjut, lihat Keamanan Transportasi HTTP.

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

    Sesi aman terjadi saat klien dan layanan membuat saluran menggunakan kunci konten (klien dan server menggunakan kunci yang sama untuk panjang percakapan, hingga dialog ditutup).

Mengatur Jenis Mandat Klien

Pilih jenis mandat klien yang sesuai. Untuk mengetahui informasi selengkapnya, lihat Memilih Jenis Mandat. Jenis mandat klien berikut ini tersedia:

  • Windows

  • Certificate

  • Digest

  • Basic

  • UserName

  • NTLM

  • IssuedToken

Bergantung pada cara Anda mengatur mode, Anda harus mengatur jenis mandat. Misalnya, jika Anda telah memilih wsHttpBinding, dan telah mengatur mode ke "Pesan," 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 Mandat Layanan

Setelah memilih jenis mandat klien, Anda harus mengatur mandat aktual untuk digunakan layanan dan klien. Pada layanan, mandat diatur menggunakan kelas ServiceCredentials dan dikembalikan oleh properti Credentials kelas ServiceHostBase. Pengikatan yang digunakan menyiratkan jenis mandat layanan, mode keamanan yang dipilih, dan jenis mandat klien. Kode berikut menetapkan sertifikat untuk mandat 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: {0}", ce.Message);
    Console.WriteLine();
}
catch (System.Exception exc)
{
    Console.WriteLine("An unforeseen error occurred: {0}", 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 Mandat Klien

Pada klien, atur nilai mandat klien menggunakan kelas ClientCredentials dan dikembalikan oleh properti ClientCredentials kelas ClientBase<TChannel>. Kode berikut menetapkan sertifikat sebagai mandat 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 @ {0}", 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