如何:保护元数据终结点

服务的元数据中可能包含恶意用户可以利用的关于您的应用程序的敏感信息。 服务使用者可能还要求一种用于获取关于服务的元数据的安全机制。 因此,有时需要使用安全终结点来发布元数据。

通常使用 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. <behaviors> 元素添加到服务的配置文件的 <system.serviceModel> 元素中。

  2. <serviceBehaviors> 元素添加到 <behaviors> 元素中。

  3. <behavior> 元素添加到 <serviceBehaviors> 元素中。

  4. name 元素的 <behavior> 属性设置为适当的值。 需要 name 属性。 下面的示例使用 mySvcBehavior 值。

  5. <serviceMetadata> 添加到 <behavior> 元素中。

  6. httpsGetEnabled 元素的 <serviceMetadata> 属性设置为 true

  7. httpsGetUrl 元素的 <serviceMetadata> 属性设置为适当的值。 请注意,如果指定绝对地址,则 URL 必须以方案 https:// 开头。 如果指定相对地址,则必须为服务主机提供一个 HTTPS 基址。 如果不设置此属性,则默认地址为 "",或者直接为服务的 HTTPS 基址。

  8. 要将该行为用于服务,请将 <service> 元素的 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()

编译代码

该代码示例使用下列命名空间:

另请参阅