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


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

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

Конечные точки метаданных обычно защищены с помощью стандартных механизмов безопасности, определенных в 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> в элемент <поведение>.

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

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

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

  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 @ {machineName}:8037/serviceModelSamples/");
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()

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

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

См. также