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


Безопасность сообщений с использованием клиента Windows без согласования учетных данных

В следующем сценарии показаны клиент и служба Windows Communication Foundation (WCF), защищенные протоколом Kerberos.

Клиент и служба находятся в одном и том же домене или в доверенных доменах.

ms735117.note(ru-ru,VS.100).gifПримечание
Различие между этим сценарием и сценарием Безопасность сообщений с клиентом Windows заключается в том, что данный сценарий не выполняет согласование учетных данных службы перед отправкой сообщения приложения. И так как для этого требуется протокол Kerberos, для этого сценария необходима среда домена Windows.

Безопасность сообщений с согласованием учетных данных

Характеристика Описание

Режим безопасности

Сообщение

Взаимодействие

Да, WS-Security с клиентами, совместимыми с профилем маркера Kerberos

Проверка подлинности (сервера)

Взаимная проверка подлинности сервера и клиента

Проверка подлинности (клиента)

Взаимная проверка подлинности сервера и клиента

Целостность

Да

Конфиденциальность

Да

Транспорт

HTTP

Привязка

WSHttpBinding

Служба

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

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

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

Код

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

ms735117.note(ru-ru,VS.100).gifПримечание
Для использования типа учетных данных Windows без согласования учетная запись пользователя службы должна иметь доступ к имени участника-службы (SPN), зарегистрированному с доменом Active Directory. Это можно сделать следующими двумя способами.

  1. Используйте учетную запись NetworkService или LocalSystem для запуска службы. Поскольку у этих учетных записей есть право доступа к SPN компьютера, устанавливаемому при присоединении компьютера к домену Active Directory, WCF автоматически создает соответствующий элемент SPN в конечной точке службы в метаданных службы (языке описания веб-служб или языке WSDL).

  2. Запустите службу из любой учетной записи домена Active Directory. В этом случае потребуется установить SPN для учетной записи домена. Это можно сделать, например, с помощью средства Setspn.exe. Создав SPN для учетной записи службы, задайте WCF публиковать это SPN в клиентах службы через метаданные (WSDL). Это можно сделать, настроив удостоверение конечной точки для предоставляемой конечной точки либо в файле конфигурации приложения, либо в коде. В следующем примере описывается программный способ публикации удостоверения.

Дополнительные сведения б имени участника-службы (SPN), протоколе Kerberos и Active Directory см. в разделе Техническое дополнение Kerberos для Windows. Дополнительные сведения б удостоверениях конечных точек см. в разделе Режимы проверки подлинности SecurityBindingElement.

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

' Create the binding.
Dim binding As New WSHttpBinding()
binding.Security.Mode = SecurityMode.Message
binding.Security.Message.ClientCredentialType = _
   MessageCredentialType.Windows

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

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

' Create the EndpointAddress with the SPN for the Identity.
Dim ea As New EndpointAddress(httpUri, _
EndpointIdentity.CreateSpnIdentity("service_spn_name"))

' Get the contract from the ICalculator interface (not shown here).
' See the sample applications for an example of the ICalculator.
Dim contract As ContractDescription = ContractDescription.GetContract(GetType(ICalculator))

' Create a new ServiceEndpoint.
Dim se As New ServiceEndpoint(contract, binding, ea)

' Add the service endpoint to the service.
myServiceHost.Description.Endpoints.Add(se)

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

' Close the service. 
myServiceHost.Close()
// Create the service host.
ServiceHost myServiceHost = new ServiceHost(typeof(Calculator));

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

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

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

// Create the EndpointAddress with the SPN for the Identity.
EndpointAddress ea = new EndpointAddress(httpUri,
    EndpointIdentity.CreateSpnIdentity("service_spn_name"));

// Get the contract from the ICalculator interface (not shown here).
// See the sample applications for an example of the ICalculator.
ContractDescription contract = ContractDescription.GetContract(
    typeof(ICalculator));

// Create a new ServiceEndpoint.
ServiceEndpoint se = new ServiceEndpoint(contract, binding, ea);

// Add the service endpoint to the service.
myServiceHost.Description.Endpoints.Add(se);

// 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 />
    <services>
      <service behaviorConfiguration="" name="ServiceModel.Calculator">
        <endpoint address="https://localhost/Calculator" 
                  binding="wsHttpBinding"
                  bindingConfiguration="KerberosBinding"
                  name="WSHttpBinding_ICalculator"
                  contract="ServiceModel.ICalculator" 
                  listenUri="net.tcp://localhost/metadata" >
         <identity>
            <servicePrincipalName value="service_spn_name" />
         </identity>
        </endpoint>
      </service>
    </services>
    <bindings>
      <wsHttpBinding>
        <binding name="KerberosBinding">
          <security>
            <message negotiateServiceCredential="false" 
                     establishSecurityContext="false" />
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
    <client />
  </system.serviceModel>
</configuration>

Клиент

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

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

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

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

Код

Следующий код служит для настройки клиента. Для режима безопасности задано значение Message, типу учетных данных клиента присвоено значение Windows. Обратите внимание: свойствам NegotiateServiceCredential и EstablishSecurityContext задается значение false.

ms735117.note(ru-ru,VS.100).gifПримечание
Для использования типа учетных данных Windows без согласования требуется настроить SPN учетной записи службы до начала обмена данными со службой. Клиент использует имя SPN, чтобы получить маркер Kerberos для проверки подлинности и обеспечения безопасности обмена данными со службой. В следующем образце показано, как настроить SPN службы для клиента. Если для создания клиента используется Служебное средство ServiceModel Metadata Utility Tool (Svcutil.exe), SPN службы будет автоматически согласовано с клиентом из метаданных службы (WSDL), при условии, что в метаданных службы содержится эта информация. Дополнительные сведения о том, как настроить включение службой своего SPN в метаданные службы см. раздел "Служба" далее.

Для получения дополнительных сведений об SPN, Kerberos и Active Directory перейдите по ссылке Техническое дополнение Kerberos для Windows. Дополнительные сведения об удостоверениях конечных точек см. в разделе Режимы проверки подлинности SecurityBindingElement.

' Create the binding.
Dim myBinding As New WSHttpBinding()
myBinding.Security.Mode = SecurityMode.Message
myBinding.Security.Message.ClientCredentialType = _
   MessageCredentialType.Windows

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

' Create the endpoint address and set the SPN identity.
' The SPN must match the identity of the service's SPN.
' If using SvcUtil to generate a configuration file, the SPN
' will be published as the <servicePrincipalName> element under the
' <identity> element.
Dim ea As New EndpointAddress(New Uri("http://machineName/calculator"), _
EndpointIdentity.CreateSpnIdentity("service_spn_name"))

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

' 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
// Create the binding.
WSHttpBinding myBinding = new WSHttpBinding();
myBinding.Security.Mode = SecurityMode.Message;
myBinding.Security.Message.ClientCredentialType =
    MessageCredentialType.Windows;

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

// Create the endpoint address and set the SPN identity.
// The SPN must match the identity of the service's SPN.
// If using SvcUtil to generate a configuration file, the SPN
// will be published as the <servicePrincipalName> element under the
// <identity> element.
EndpointAddress ea = new EndpointAddress(
new Uri("http://machineName/Calculator"),
EndpointIdentity.CreateSpnIdentity("service_spn_name"));

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

// Begin using the client.

try
{
    cc.Open();
    Console.WriteLine(cc.Add(200, 1111));
    Console.ReadLine();

    // Close the client.
    cc.Close();
}

Конфигурация

Следующий код служит для настройки клиента. Обратите внимание: элемент <ServicePrincipalName> должен соответствовать SPN службы, установленному для учетной записи службы в домене Active Directory.

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.serviceModel>
    <bindings>
      <wsHttpBinding>
        <binding name="WSHttpBinding_ICalculator" >
          <security mode="Message">
            <message clientCredentialType="Windows" 
                     negotiateServiceCredential="false"
                     establishSecurityContext="false" />
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
    <client>
      <endpoint address="https://localhost/Calculator" 
                binding="wsHttpBinding"
                bindingConfiguration="WSHttpBinding_ICalculator"
                contract="ICalculator"
                name="WSHttpBinding_ICalculator">
        <identity>
          <servicePrincipalName value="service_spn_name" />
        </identity>
      </endpoint>
    </client>
  </system.serviceModel>
</configuration>

См. также

Основные понятия

Общие сведения о безопасности
Идентификация и проверка подлинности службы

Другие ресурсы

Модель безопасности для Windows Server App Fabric