Поделиться через


Безопасность сообщений при использовании клиентом сертификата

В следующем сценарии показан клиент Windows Communication Foundation (WCF), защищенный с помощью режима безопасности сообщений. Проверка подлинности клиента и службы выполняется с помощью сертификатов. Дополнительные сведения см. в разделе "Безопасность распределенных приложений".

Снимок экрана: клиент с сертификатом.

Пример приложения см. в разделе "Сертификат безопасности сообщений".

Characteristic Description
Режим безопасности Сообщение
Совместимость Только WCF
Проверка подлинности (сервера) Использование сертификатов служб
Проверка подлинности (клиента) Использование сертификатов клиента
Целостность Да
Конфиденциальность Да
Транспорт HTTP
Привязка WSHttpBinding

Service

Предполагается, что представленные ниже код и конфигурация выполняются независимо. Выполните одно из следующих действий:

  • Создайте автономную службу, используя код без конфигурации.

  • Создайте службу, используя предоставленную конфигурацию, но не определяйте конечные точки.

Код

В следующем коде показано создание конечной точки службы, которая использует безопасность сообщений для установления защищенного контекста.

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

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

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

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

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

' 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)
myServiceHost.AddServiceEndpoint(GetType(ICalculator), binding, "")

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

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

' Close the service.
myServiceHost.Close()

Настройка

Вместо кода можно использовать следующую конфигурацию.

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

Клиент

Предполагается, что представленные ниже код и конфигурация выполняются независимо. Выполните одно из следующих действий:

  • Создайте автономный клиент, используя код (и код клиента).

  • Создайте клиент, который не определяет никаких адресов конечных точек. Вместо этого используйте конструктор клиента, который принимает в качестве аргумента имя конфигурации. Например:

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

Код

Следующий код служит для создания клиента. Привязка осуществляется к безопасности режима сообщений, и типу учетных данных клиента присваивается значение Certificate.

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

// 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");

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

' Create the endpoint address.
Dim ea As New EndpointAddress("http://machineName/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")

' 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

Настройка

В следующей конфигурации задается сертификат клиента с помощью поведения конечной точки. Дополнительные сведения см. в разделе Работа с сертификатами. Код также использует <identity> элемент для указания dns-системы доменных имен ожидаемого удостоверения сервера. Дополнительные сведения об удостоверениях см. в разделе "Удостоверение службы" и "Проверка подлинности".

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.serviceModel>
    <behaviors>
      <endpointBehaviors>
        <behavior name="endpointCredentialsBehavior">
          <clientCredentials>
            <clientCertificate findValue="Cohowinery.com"
               storeLocation="LocalMachine"
              x509FindType="FindBySubjectName" />
          </clientCredentials>
        </behavior>
      </endpointBehaviors>
    </behaviors>
    <bindings>
      <wsHttpBinding>
        <binding name="WSHttpBinding_ICalculator" >
          <security mode="Message">
            <message clientCredentialType="Certificate" />
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
    <client>
      <endpoint address="http://machineName/Calculator"
                behaviorConfiguration="endpointCredentialsBehavior"
                binding="wsHttpBinding"
                bindingConfiguration="WSHttpBinding_ICalculator"
                contract="ICalculator"
                name="WSHttpBinding_ICalculator">
        <identity>
          <dns value="Contoso.com" />
        </identity>
      </endpoint>
    </client>
  </system.serviceModel>
</configuration>

См. также