如何:使用传输安全和消息凭据

同时使用传输凭据和消息凭据来保护服务,可以发挥 Windows Communication Foundation (WCF) 中的传输安全模式和消息安全模式的优势。 总之,传输层安全提供了完整性和机密性,而消息层安全则提供了严格的传输安全机制所不可能提供的多种凭据。 本主题演示使用 WSHttpBindingNetTcpBinding 绑定通过消息凭据实现传输的基本步骤。 有关设置安全模式的详细信息,请参阅如何:设置安全模式

在将安全模式设置为 TransportWithMessageCredential 时,传输会确定实际提供传输级安全的机制。 对于 HTTP,该机制为基于 HTTP 的安全套接字层 (SSL)(SSL over HTPP,或 HTTPS);对于 TCP,该机制为 SSL over TCP 或 Windows。

如果传输为 HTTP(使用 WSHttpBinding),则由 SSL over HTTP 提供传输级安全。 在这种情况下,必须使用绑定到某个端口的 SSL 证书来配置承载服务的计算机,如本主题稍后所示。

如果传输为 TCP(使用 NetTcpBinding),则默认情况下提供的传输级安全为 Windows 安全,即 SSL over TCP。 使用 SSL over TCP 时,必须使用 SetCertificate 方法指定证书,如本主题稍后所示。

使用 WSHttpBinding 和证书来获得传输安全(在代码中)

  1. 使用 HttpCfg.exe 工具将 SSL 证书绑定到计算机上的某个端口。 有关详细信息,请参阅如何:使用 SSL 证书配置端口

  2. 创建 WSHttpBinding 类的一个实例,并将 Mode 属性设置为 TransportWithMessageCredential

  3. ClientCredentialType 属性设置为适当的值。 (有关详细信息,请参阅选择凭据类型。)以下代码使用 Certificate 值。

  4. 用适当的基址创建 Uri 类的一个实例。 请注意,该地址必须使用“HTTPS”方案,且必须包含计算机的实际名称以及 SSL 证书绑定到的端口号。 (也可以在配置中设置基址。)

  5. 使用 AddServiceEndpoint 方法添加一个服务终结点。

  6. 创建 ServiceHost 的实例并调用 Open 方法,如下面的代码所示。

    WSHttpBinding b = new WSHttpBinding();
    b.Security.Mode = SecurityMode.TransportWithMessageCredential;
    b.Security.Message.ClientCredentialType = MessageCredentialType.Certificate;
    
    // The SSL certificate is bound to port 8006 using the HttpCfg.exe tool.
    Uri httpsAddress = new Uri("https://localMachineName:8006/base");
    ServiceHost sh = new ServiceHost(typeof(Calculator), httpsAddress);
    sh.AddServiceEndpoint(typeof(ICalculator), b, "HttpsCalculator");
    sh.Open();
    Console.WriteLine("Listening");
    Console.ReadLine();
    
    Dim b As New WSHttpBinding()
    b.Security.Mode = SecurityMode.TransportWithMessageCredential
    b.Security.Message.ClientCredentialType = MessageCredentialType.Certificate
    
    ' The SSL certificate is bound to port 8006 using the HttpCfg.exe tool.
    Dim httpsAddress As New Uri("https://localMachineName:8006/base")
    Dim sh As New ServiceHost(GetType(Calculator), httpsAddress)
    sh.AddServiceEndpoint(GetType(ICalculator), b, "HttpsCalculator")
    sh.Open()
    Console.WriteLine("Listening")
    Console.ReadLine()
    

使用 NetTcpBinding 和证书来获得传输安全(在代码中)

  1. 创建 NetTcpBinding 类的一个实例,并将 Mode 属性设置为 TransportWithMessageCredential

  2. ClientCredentialType 设置为适当的值。 下面的代码使用 Certificate 值。

  3. 用适当的基址创建 Uri 类的一个实例。 请注意,该地址必须使用“net.tcp”方案。 (也可以在配置中设置基址。)

  4. 创建 ServiceHost 类的实例。

  5. 使用 SetCertificate 类的 X509CertificateRecipientServiceCredential 方法显式设置服务的 X.509 证书。

  6. 使用 AddServiceEndpoint 方法添加一个服务终结点。

  7. 调用 Open 方法,如下面的代码所示。

    NetTcpBinding b = new NetTcpBinding(SecurityMode.TransportWithMessageCredential);
    b.Security.Message.ClientCredentialType = MessageCredentialType.Certificate;
    Uri netTcpAddress = new Uri("net.tcp://baseAddress");
    ServiceHost sh = new ServiceHost(typeof(Calculator), netTcpAddress);
    sh.Credentials.ServiceCertificate.SetCertificate(
        StoreLocation.LocalMachine, StoreName.My,
        X509FindType.FindByIssuerName, "Contoso.com");
    sh.AddServiceEndpoint(typeof(ICalculator), b, "TcpCalculator");
    sh.Open();
    Console.WriteLine("Listening");
    Console.ReadLine();
    
    Dim b As New NetTcpBinding(SecurityMode.TransportWithMessageCredential)
    b.Security.Message.ClientCredentialType = MessageCredentialType.Certificate
    Dim netTcpAddress As New Uri("net.tcp://baseAddress")
    Dim sh As New ServiceHost(GetType(Calculator), netTcpAddress)
    sh.Credentials.ServiceCertificate.SetCertificate(StoreLocation.LocalMachine, StoreName.My, X509FindType.FindByIssuerName, "Contoso.com")
    sh.AddServiceEndpoint(GetType(ICalculator), b, "TcpCalculator")
    sh.Open()
    Console.WriteLine("Listening")
    Console.ReadLine()
    

使用 NetTcpBinding 和 Windows 来获得传输安全(在代码中)

  1. 创建 NetTcpBinding 类的一个实例,并将 Mode 属性设置为 TransportWithMessageCredential

  2. 将传输安全设置为使用 Windows,方法是将 ClientCredentialType 设置为 Windows。 (请注意,这是默认值。)

  3. ClientCredentialType 设置为适当的值。 下面的代码使用 Certificate 值。

  4. 用适当的基址创建 Uri 类的一个实例。 请注意,该地址必须使用“net.tcp”方案。 (也可以在配置中设置基址。)

  5. 创建 ServiceHost 类的实例。

  6. 使用 SetCertificate 类的 X509CertificateRecipientServiceCredential 方法显式设置服务的 X.509 证书。

  7. 使用 AddServiceEndpoint 方法添加一个服务终结点。

  8. 调用 Open 方法,如下面的代码所示。

    NetTcpBinding b = new NetTcpBinding(SecurityMode.TransportWithMessageCredential);
    b.Security.Transport.ClientCredentialType = TcpClientCredentialType.Windows;
    b.Security.Message.ClientCredentialType = MessageCredentialType.Certificate;
    Uri netTcpAddress = new Uri("net.tcp://Tcp");
    ServiceHost sh = new ServiceHost(typeof(Calculator), netTcpAddress);
    sh.Credentials.ServiceCertificate.SetCertificate(
        StoreLocation.LocalMachine, StoreName.My,
        X509FindType.FindByIssuerName, "Contoso.com");
    sh.AddServiceEndpoint(typeof(ICalculator), b, "TcpCalculator");
    sh.Open();
    Console.WriteLine("Listening");
    Console.ReadLine();
    
    Dim b As New NetTcpBinding(SecurityMode.TransportWithMessageCredential)
    b.Security.Transport.ClientCredentialType = TcpClientCredentialType.Windows
    b.Security.Message.ClientCredentialType = MessageCredentialType.Certificate
    Dim netTcpAddress As New Uri("net.tcp://Tcp")
    Dim sh As New ServiceHost(GetType(Calculator), netTcpAddress)
    sh.Credentials.ServiceCertificate.SetCertificate(StoreLocation.LocalMachine, StoreName.My, X509FindType.FindByIssuerName, "Contoso.com")
    sh.AddServiceEndpoint(GetType(ICalculator), b, "TcpCalculator")
    sh.Open()
    Console.WriteLine("Listening")
    Console.ReadLine()
    

使用配置

使用 WSHttpBinding

  1. 使用绑定到某个端口的 SSL 证书配置计算机。 (有关详细信息,请参阅如何:使用 SSL 证书配置端口)。 对于此配置,无需设置 <transport> 元素值。

  2. 指定消息级安全的客户端凭据类型。 下面的示例将 <message> 元素的 clientCredentialType 属性设置为 UserName

    <wsHttpBinding>  
    <binding name="WsHttpBinding_ICalculator">  
            <security mode="TransportWithMessageCredential" >  
               <message clientCredentialType="UserName" />  
            </security>  
    </binding>  
    </wsHttpBinding>  
    

使用 NetTcpBinding 和证书来获得传输安全

  1. 对于 SSL over TCP,必须在 <behaviors> 元素中显式指定证书。 下面的示例指定一个证书,该证书由其颁发机构存储在默认存储位置(本地计算机和个人存储)。

    <behaviors>  
     <serviceBehaviors>  
       <behavior name="mySvcBehavior">  
           <serviceCredentials>  
             <serviceCertificate findValue="contoso.com"  
                                 x509FindType="FindByIssuerName" />  
           </serviceCredentials>  
       </behavior>  
     </serviceBehaviors>  
    </behaviors>  
    
  2. <netTcpBinding> 添加到绑定节

  3. 添加一个绑定元素,并将 name 属性设置为适当的值。

  4. 添加一个 <security> 元素,并将 mode 属性设置为 TransportWithMessageCredential

  5. 添加一个 <message> 元素,并将 clientCredentialType 属性设置为适当的值。

    <bindings>  
    <netTcpBinding>  
      <binding name="myTcpBinding">  
        <security mode="TransportWithMessageCredential" >  
           <message clientCredentialType="Windows" />  
        </security>  
      </binding>  
    </netTcpBinding>  
    </bindings>  
    

使用 NetTcpBinding 和 Windows 来获得传输安全

  1. <netTcpBinding> 添加到绑定节,

  2. 添加一个 <binding> 元素,并将 name 属性设置为适当的值。

  3. 添加一个 <security> 元素,并将 mode 属性设置为 TransportWithMessageCredential

  4. 添加一个 <transport> 元素,并将 clientCredentialType 属性设置为 Windows

  5. 添加一个 <message> 元素,并将 clientCredentialType 属性设置为适当的值。 下面的代码将该值设置为一个证书。

    <bindings>  
    <netTcpBinding>  
      <binding name="myTcpBinding">  
        <security mode="TransportWithMessageCredential" >  
           <transport clientCredentialType="Windows" />  
           <message clientCredentialType="Certificate" />  
        </security>  
      </binding>  
    </netTcpBinding>  
    </bindings>  
    

另请参阅