Bagikan melalui


Keamanan Pesan dengan Sertifikat Timbal Balik

Skenario berikut menunjukkan layanan Windows Communication Foundation (WCF) dan klien diamankan menggunakan mode keamanan pesan. Klien dan layanan diautentikasi dengan sertifikat.

Skenario ini dapat dioperasikan karena menggunakan WS-Security dengan profil token sertifikat X.509.

Catatan

Skenario ini tidak melakukan negosiasi sertifikat layanan. Sertifikat layanan harus diberikan kepada klien sebelum komunikasi apa pun. Sertifikat server dapat didistribusikan dengan aplikasi atau disediakan dalam komunikasi out-of-band.

Message security with mutual certificates

Karakteristik Deskripsi
Mode Keamanan Pesan
Interoperabilitas Ya, dengan WS-Security dan profil token sertifikat X.509 yang kompatibel dengan klien dan layanan.
Autentikasi Autentikasi timbal balik antara server dan klien.
Integritas Ya
Kerahasiaan Ya
Transportasi HTTP
Pengikatan WSHttpBinding

Layanan

Kode dan konfigurasi berikut dimaksudkan untuk berjalan secara independen. Lakukan salah satu langkah berikut:

  • Buat layanan mandiri menggunakan kode tanpa konfigurasi.

  • Buat layanan menggunakan konfigurasi yang disediakan, tetapi jangan menentukan titik akhir apa pun.

Kode

Kode berikut menunjukkan membuat titik akhir layanan yang menggunakan keamanan pesan. Layanan ini memerlukan sertifikat untuk mengautentikasi dirinya sendiri.

// Create the binding.
WSHttpBinding binding = new WSHttpBinding();
binding.Security.Mode = SecurityMode.Message;
binding.Security.Message.ClientCredentialType =
    MessageCredentialType.Certificate;
binding.Security.Message.NegotiateServiceCredential = false;
binding.Security.Message.EstablishSecurityContext = false;

// Create the URI for the endpoint.
Uri httpUri = new Uri("http://localhost/Calculator");

// Create the service host.
ServiceHost myServiceHost =
    new ServiceHost(typeof(Calculator), httpUri);

// Specify a certificate to authenticate the service.
myServiceHost.Credentials.ServiceCertificate.SetCertificate(
    StoreLocation.LocalMachine,
    StoreName.My,
    X509FindType.FindBySubjectName,
    "contoso.com");

// Add an endpoint to the service.
myServiceHost.AddServiceEndpoint(typeof(ICalculator), binding, "");

// Open the service.
myServiceHost.Open();
Console.WriteLine("Listening...");
Console.ReadLine();

// Close the service.
myServiceHost.Close();
' Create the binding.
Dim binding As New WSHttpBinding()
binding.Security.Mode = SecurityMode.Message
binding.Security.Message.ClientCredentialType = _
MessageCredentialType.Certificate
binding.Security.Message.NegotiateServiceCredential = False
binding.Security.Message.EstablishSecurityContext = False

' Create the URI for the endpoint.
Dim httpUri As New Uri("http://localhost/Calculator")

' Create the service host.
Dim myServiceHost As New ServiceHost(GetType(ServiceModel.Calculator), httpUri)

' Specify a certificate to authenticate the service.
myServiceHost.Credentials.ServiceCertificate.SetCertificate(StoreLocation.LocalMachine, _
StoreName.My, X509FindType.FindBySubjectName, "contoso.com")

' Add an endpoint to the service.
myServiceHost.AddServiceEndpoint(GetType(ICalculator), binding, "")

' Open the service.
myServiceHost.Open()
Console.WriteLine("Listening...")
Console.ReadLine()

' Close the service.
myServiceHost.Close()

Konfigurasi

Konfigurasi berikut dapat digunakan sebagai pengganti kode untuk membuat layanan yang sama.

<?xml version="1.0" encoding="utf-8"?>  
<configuration>  
  <system.serviceModel>  
    <behaviors>  
      <serviceBehaviors>  
        <behavior name="serviceCredentialBehavior">  
          <serviceCredentials>  
            <serviceCertificate findValue="Contoso.com"
                                storeLocation="LocalMachine"  
                                storeName="My"
                                x509FindType="FindBySubjectName" />  
          </serviceCredentials>  
        </behavior>  
      </serviceBehaviors>  
    </behaviors>  
    <services>  
      <service behaviorConfiguration="serviceCredentialBehavior"
               name="ServiceModel.Calculator">  
        <endpoint address="http://localhost/Calculator"
                  binding="wsHttpBinding"  
                  bindingConfiguration="InteropCertificateBinding"  
                  name="WSHttpBinding_ICalculator"  
                  contract="ServiceModel.ICalculator" />  
      </service>  
    </services>  
    <bindings>  
      <wsHttpBinding>  
        <binding name="InteropCertificateBinding">  
          <security mode="Message">  
            <message clientCredentialType="Certificate"  
                     negotiateServiceCredential="false"  
                     establishSecurityContext="false" />  
          </security>  
        </binding>  
      </wsHttpBinding>  
    </bindings>  
    <client />  
  </system.serviceModel>  
</configuration>  

Klien

Kode dan konfigurasi berikut dimaksudkan untuk berjalan secara independen. Lakukan salah satu langkah berikut:

  • Buat klien mandiri menggunakan kode (dan kode klien).

  • Buat klien yang tidak menentukan alamat titik akhir apa pun. Sebagai gantinya, gunakan konstruktor klien yang mengambil nama konfigurasi sebagai argumen. Misalnya:

    CalculatorClient cc = new CalculatorClient("EndpointConfigurationName");
    
    Dim cc As New CalculatorClient("EndpointConfigurationName")
    

Kode

Kode berikut membuat klien. Mode keamanan diatur ke Pesan, dan jenis kredensial klien diatur ke Sertifikat.

// Create the binding.
WSHttpBinding myBinding = new WSHttpBinding();
myBinding.Security.Mode = SecurityMode.Message;
myBinding.Security.Message.ClientCredentialType =
    MessageCredentialType.Certificate;

// Disable credential negotiation and the establishment of
// a security context.
myBinding.Security.Message.NegotiateServiceCredential = false;
myBinding.Security.Message.EstablishSecurityContext = false;

// Create the endpoint address.
EndpointAddress ea = new
    EndpointAddress("http://machineName/Calculator");

// Create the client.
CalculatorClient cc =
    new CalculatorClient(myBinding, ea);

// Specify a certificate to use for authenticating the client.
cc.ClientCredentials.ClientCertificate.SetCertificate(
    StoreLocation.CurrentUser,
    StoreName.My,
    X509FindType.FindBySubjectName,
    "Cohowinery.com");

// Specify a default certificate for the service.
cc.ClientCredentials.ServiceCertificate.SetDefaultCertificate(
    StoreLocation.CurrentUser,
    StoreName.TrustedPeople,
    X509FindType.FindBySubjectName,
    "Contoso.com");

// Begin using the client.
try
{
    cc.Open();
    Console.WriteLine(cc.Add(200, 1111));
    Console.ReadLine();

    // Close the client.
    cc.Close();
}
' Create the binding.
Dim myBinding As New WSHttpBinding()
myBinding.Security.Mode = SecurityMode.Message
myBinding.Security.Message.ClientCredentialType = MessageCredentialType.Certificate

' Disable credential negotiation and the establishment of
' a security context.
myBinding.Security.Message.NegotiateServiceCredential = False
myBinding.Security.Message.EstablishSecurityContext = False

' Create the endpoint address.
Dim ea As New EndpointAddress("http://localhost/Calculator")

' Create the client.
Dim cc As New CalculatorClient(myBinding, ea)

' Specify a certificate to use for authenticating the client.
cc.ClientCredentials.ClientCertificate.SetCertificate( _
    StoreLocation.CurrentUser, StoreName.My, _
    X509FindType.FindBySubjectName, "Cohowinery.com")

' Specify a default certificate for the service.
cc.ClientCredentials.ServiceCertificate.SetDefaultCertificate( _
    StoreLocation.CurrentUser, StoreName.TrustedPeople, _
    X509FindType.FindBySubjectName, "Contoso.com")

' Begin using the client.
Try
    cc.Open()

    Console.WriteLine(cc.Add(100, 11))
    Console.ReadLine()

    ' Close the client.
    cc.Close()
Catch tex As TimeoutException
    Console.WriteLine(tex.Message)
    cc.Abort()
Catch cex As CommunicationException
    Console.WriteLine(cex.Message)
    cc.Abort()
Finally
    Console.WriteLine("Closed the client")
    Console.ReadLine()
End Try

Konfigurasi

Berikut ini mengonfigurasi klien. Sertifikat klien harus ditentukan menggunakan <clientCertificate>. Selain itu, sertifikat layanan ditentukan menggunakan <defaultCertificate>.

<?xml version="1.0" encoding="utf-8"?>  
<configuration>  
  <system.serviceModel>  
    <behaviors>  
      <endpointBehaviors>  
        <behavior name="ClientCredentialsBehavior">  
          <clientCredentials>  
            <clientCertificate findValue="Cohowinery.com"
                 storeLocation="CurrentUser"  
                 storeName="My"  
                 x509FindType="FindBySubjectName" />  
            <serviceCertificate>  
              <defaultCertificate findValue="Contoso.com"
                                  storeLocation="CurrentUser"  
                                  storeName="TrustedPeople"  
                                  x509FindType="FindBySubjectName" />  
            </serviceCertificate>  
          </clientCredentials>  
        </behavior>  
      </endpointBehaviors>  
    </behaviors>  
    <bindings>  
      <wsHttpBinding>  
        <binding name="WSHttpBinding_ICalculator" >  
          <security mode="Message">  
            <message clientCredentialType="Certificate"
                     negotiateServiceCredential="false"  
                     establishSecurityContext="false" />  
          </security>  
        </binding>  
      </wsHttpBinding>  
    </bindings>  
    <client>  
      <endpoint address="http://machineName/Calculator"
                behaviorConfiguration="ClientCredentialsBehavior"  
                binding="wsHttpBinding"
                bindingConfiguration="WSHttpBinding_ICalculator"  
                contract="ICalculator"  
                name="WSHttpBinding_ICalculator">  
        <identity>  
          <certificate encodedValue="Encoded_Value_Not_Shown" />  
        </identity>  
      </endpoint>  
    </client>  
  </system.serviceModel>  
</configuration>  

Lihat juga