Практическое руководство. Защита конечных точек метаданных

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

Конечные точки метаданных обычно защищены с помощью стандартных механизмов безопасности, определенных в Windows Communication Foundation (WCF) для защиты конечных точек приложений. Дополнительные сведения см. в обзоре безопасности.

В этом разделе содержится пошаговое руководство по созданию конечной точки, безопасность которой обеспечивается SSL-сертификатом, то есть конечной точкой HTTPS.

Добавление защищенной конечной точки метаданных HTTPS GET в код

  1. Настройте порт с соответствующим сертификатом X.509. Сертификат должен поступать из доверенного центра, и он должен иметь предполагаемое использование "Авторизация службы". Для подключения сертификата к порту необходимо использовать средство HttpCfg.exe. Узнайте , как настроить порт с помощью SSL-сертификата.

    Внимание

    Субъект сертификата или его служба доменных имен (DNS) должны соответствовать имени компьютера. Это важно, так как одним из первых шагов механизма HTTPS является проверка соответствия сертификата универсальному коду ресурса (URI) и адресу, для которого он вызван.

  2. Создайте новый экземпляр класса ServiceMetadataBehavior.

  3. Задайте свойству HttpsGetEnabled класса ServiceMetadataBehavior значение true.

  4. Присвойте свойству HttpsGetUrl соответствующее значение URL-адреса. Обратите внимание, что если указать абсолютный адрес, URL-адрес должен начинаться со схемы https://. При указании относительного адреса необходимо определить базовый адрес HTTPS узла службы. Если это свойство службы не задано, за адрес по умолчанию принимается "" или непосредственно базовый адрес HTTPS службы.

  5. Создайте экземпляр коллекции поведений, который возвращает свойство Behaviors класса ServiceDescription в соответствии со следующим кодом.

    // Create a new metadata behavior object and set its properties to
    // create a secure endpoint.
    ServiceMetadataBehavior sb = new ServiceMetadataBehavior();
    sb.HttpsGetEnabled = true;
    sb.HttpsGetUrl = new Uri("https://myMachineName:8036/myEndpoint");
    myServiceHost.Description.Behaviors.Add(sb);
    
    myServiceHost.Open();
    
    ' Create a new metadata behavior object and set its properties to 
    ' create a secure endpoint. 
    Dim sb As New ServiceMetadataBehavior()
    
    With sb
        .HttpsGetEnabled = True
        .HttpsGetUrl = New Uri("https://myMachineName:8036/myEndpoint")
    End With
    
    With myServiceHost
        .Description.Behaviors.Add(sb)
        .Open()
    End With
    

Добавление защищенной конечной точки метаданных HTTPS GET в конфигурацию

  1. <Добавьте элемент поведения> в <элемент system.serviceModel> файла конфигурации для службы.

  2. Добавьте элемент ServiceBehaviors> в< элемент behaviors>.<

  3. <Добавьте элемент поведения> в <serviceBehaviors> элемент.

  4. Задайте атрибуту name элемента <behavior> соответствующее значение. Атрибут name является обязательным. В приведенном ниже примере используется значение mySvcBehavior.

  5. Добавьте в элемент метаданные <<behavior> serviceMetadata.>

  6. Задайте атрибуту httpsGetEnabled элемента <serviceMetadata> значение true.

  7. Задайте атрибуту httpsGetUrl элемента <serviceMetadata> соответствующее значение. Обратите внимание, что если указать абсолютный адрес, URL-адрес должен начинаться со схемы https://. При указании относительного адреса необходимо определить базовый адрес HTTPS узла службы. Если это свойство службы не задано, за адрес по умолчанию принимается "" или непосредственно базовый адрес HTTPS службы.

  8. Чтобы использовать поведение со службой, задайте behaviorConfiguration атрибут< элемента службы> значением атрибута имени элемента поведения. В следующем примере приводится полный код конфигурации.

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
     <system.serviceModel>
      <behaviors>
       <serviceBehaviors>
        <behavior name="mySvcBehavior">
         <serviceMetadata httpsGetEnabled="true"
              httpsGetUrl="https://localhost:8036/calcMetadata" />
        </behavior>
       </serviceBehaviors>
      </behaviors>
     <services>
      <service behaviorConfiguration="mySvcBehavior"
            name="Microsoft.Security.Samples.Calculator">
       <endpoint address="http://localhost:8037/ServiceModelSamples/calculator"
       binding="wsHttpBinding" bindingConfiguration=""
       contract="Microsoft.Security.Samples.ICalculator" />
      </service>
     </services>
    </system.serviceModel>
    </configuration>
    

Пример

В следующем примере создается экземпляр класса ServiceHost и добавляется конечная точка. Затем создается экземпляр класса ServiceMetadataBehavior и задаются свойства для создания защищенной точки обмена метаданными.

WSHttpBinding myBinding = new WSHttpBinding();
myBinding.Security.Mode = SecurityMode.Message;
myBinding.Security.Message.ClientCredentialType =
    MessageCredentialType.Windows;

// Create the Type instances for later use and the URI for
// the base address.
Type contractType = typeof(ICalculator);
Type serviceType = typeof(Calculator);
Uri baseAddress = new
    Uri("http://localhost:8037/serviceModelSamples/");

// Create the ServiceHost and add an endpoint.
ServiceHost myServiceHost =
    new ServiceHost(serviceType, baseAddress);
myServiceHost.AddServiceEndpoint
    (contractType, myBinding, "secureCalculator");
// Create a new metadata behavior object and set its properties to
// create a secure endpoint.
ServiceMetadataBehavior sb = new ServiceMetadataBehavior();
sb.HttpsGetEnabled = true;
sb.HttpsGetUrl = new Uri("https://myMachineName:8036/myEndpoint");
myServiceHost.Description.Behaviors.Add(sb);

myServiceHost.Open();
// Use the GetHostEntry method to return the actual machine name.
string machineName = System.Net.Dns.GetHostEntry("").HostName ;
Console.WriteLine("Listening @ {0}:8037/serviceModelSamples/", machineName);
Console.WriteLine("Press Enter to close the service");
Console.ReadLine();
myServiceHost.Close();
Dim myBinding As New WSHttpBinding()
With myBinding.Security
    .Mode = SecurityMode.Message
    .Message.ClientCredentialType = MessageCredentialType.Windows
End With

' Create the Type instances for later use and the URI for 
' the base address.
Dim contractType = GetType(ICalculator)
Dim serviceType = GetType(Calculator)
Dim baseAddress As New Uri("http://localhost:8037/serviceModelSamples/")

' Create the ServiceHost and add an endpoint. 
Dim myServiceHost As New ServiceHost(serviceType, baseAddress)
myServiceHost.AddServiceEndpoint(contractType, myBinding, "secureCalculator")

' Create a new metadata behavior object and set its properties to 
' create a secure endpoint. 
Dim sb As New ServiceMetadataBehavior()

With sb
    .HttpsGetEnabled = True
    .HttpsGetUrl = New Uri("https://myMachineName:8036/myEndpoint")
End With

With myServiceHost
    .Description.Behaviors.Add(sb)
    .Open()
End With

' Use the GetHostEntry method to return the actual machine name.
Dim machineName = System.Net.Dns.GetHostEntry("").HostName
Console.WriteLine("Listening @ {0}:8037/serviceModelSamples/", machineName)
Console.WriteLine("Press Enter to close the service")
Console.ReadLine()
myServiceHost.Close()

Компиляция кода

В примере кода используются следующие пространства имен:

См. также