使用证书客户端的消息安全

下面的方案演示使用消息安全模式保护的 Windows Communication Foundation (WCF) 客户端和服务。 使用证书对客户端和服务进行身份验证。 有关详细信息,请参阅分布式应用程序安全

Screenshot that shows a client with certificate.

有关示例应用程序,请参阅消息安全证书

特征 说明
安全模式 消息
互操作性 仅 WCF
身份验证(服务器) 使用服务证书
身份验证(客户端) 使用客户端证书
完整性
机密性
Transport HTTP
绑定 WSHttpBinding

服务

下面的代码和配置应独立运行。 执行下列操作之一:

  • 使用代码(而不使用配置)创建独立服务。

  • 使用提供的配置创建服务,但不定义任何终结点。

代码

下面的代码演示如何创建一个使用消息安全来建立安全上下文的服务终结点。

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

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

// Create the service host.
ServiceHost myServiceHost =
    new ServiceHost(typeof(Calculator), httpUri);
myServiceHost.AddServiceEndpoint(typeof(ICalculator), binding, "");

// Specify a certificate to authenticate the service.
myServiceHost.Credentials.ServiceCertificate.
    SetCertificate(StoreLocation.LocalMachine,
    StoreName.My,
    X509FindType.FindBySubjectName,
    "Contoso.com");

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

// Close the service.
myServiceHost.Close();
' Create the binding.
Dim binding As New WSHttpBinding()
binding.Security.Mode = SecurityMode.Message
binding.Security.Message.ClientCredentialType = _
    MessageCredentialType.Certificate

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

' Create the service host.
Dim myServiceHost As New ServiceHost(GetType(ServiceModel.Calculator), httpUri)
myServiceHost.AddServiceEndpoint(GetType(ICalculator), binding, "")

' Specify a certificate to authenticate the service.
myServiceHost.Credentials.ServiceCertificate.SetCertificate( _
   StoreLocation.LocalMachine, StoreName.My, _
   X509FindType.FindBySubjectName, "Contoso.com")

' 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>  
      <serviceBehaviors>  
        <behavior name="ServiceCredentialsBehavior">  
          <serviceCredentials>  
            <serviceCertificate findValue="Contoso.com"  
                                x509FindType="FindBySubjectName" />  
          </serviceCredentials>  
        </behavior>  
      </serviceBehaviors>  
    </behaviors>  
    <services>  
      <service behaviorConfiguration="ServiceCredentialsBehavior"
               name="ServiceModel.Calculator">  
        <endpoint address="http://localhost/Calculator"
                  binding="wsHttpBinding"  
                  bindingConfiguration="MessageAndCertificateClient"
                  name="SecuredByClientCertificate"  
                  contract="ServiceModel.ICalculator" />  
      </service>  
    </services>  
    <bindings>  
      <wsHttpBinding>  
        <binding name="WSHttpBinding_ICalculator">  
          <security mode="Message">  
            <message clientCredentialType="Certificate" />  
          </security>  
        </binding>  
      </wsHttpBinding>  
    </bindings>  
    <client />  
  </system.serviceModel>  
</configuration>  

客户端

下面的代码和配置应独立运行。 执行下列操作之一:

  • 使用代码(和客户端代码)创建独立客户端。

  • 创建不定义任何终结点地址的客户端。 而使用将配置名称作为自变量的客户端构造函数。 例如:

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

代码

下面的代码创建客户端。 绑定设置为消息模式安全,客户端凭据类型设置为 Certificate

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

// Create the endpoint address.
EndpointAddress ea = new
    EndpointAddress("http://machineName/Calculator");

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

// Specify a certificate to use for authenticating the client.
cc.ClientCredentials.ClientCertificate.SetCertificate(
    StoreLocation.CurrentUser,
    StoreName.My,
    X509FindType.FindBySubjectName,
    "Cohowinery.com");

// Begin using the client.
try
{
    cc.Open();
    Console.WriteLine(cc.Add(200, 1111));
    Console.ReadLine();

    // Close the client.
    cc.Close();
}
' Create the binding.
Dim myBinding As New WSHttpBinding()
myBinding.Security.Mode = SecurityMode.Message
myBinding.Security.Message.ClientCredentialType = _
   MessageCredentialType.Certificate

' Create the endpoint address.
Dim ea As New EndpointAddress("http://machineName/Calculator")

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

' Specify a certificate to use for authenticating the client.
cc.ClientCredentials.ClientCertificate.SetCertificate( _
   StoreLocation.CurrentUser, StoreName.My, _
   X509FindType.FindBySubjectName, "Cohowinery.com")

' 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

配置

下面的配置使用终结点行为指定客户端证书。 有关证书的详细信息,请参阅使用证书。 该代码还使用 <identity> 元素来指定预期服务器标识的域名系统 (DNS)。 有关标识的详细信息,请参阅服务标识和身份验证

<?xml version="1.0" encoding="utf-8"?>  
<configuration>  
  <system.serviceModel>  
    <behaviors>  
      <endpointBehaviors>  
        <behavior name="endpointCredentialsBehavior">  
          <clientCredentials>  
            <clientCertificate findValue="Cohowinery.com"
               storeLocation="LocalMachine"  
              x509FindType="FindBySubjectName" />  
          </clientCredentials>  
        </behavior>  
      </endpointBehaviors>  
    </behaviors>  
    <bindings>  
      <wsHttpBinding>  
        <binding name="WSHttpBinding_ICalculator" >  
          <security mode="Message">  
            <message clientCredentialType="Certificate" />  
          </security>  
        </binding>  
      </wsHttpBinding>  
    </bindings>  
    <client>  
      <endpoint address="http://machineName/Calculator"
                behaviorConfiguration="endpointCredentialsBehavior"  
                binding="wsHttpBinding"  
                bindingConfiguration="WSHttpBinding_ICalculator"  
                contract="ICalculator"  
                name="WSHttpBinding_ICalculator">  
        <identity>  
          <dns value="Contoso.com" />  
        </identity>  
      </endpoint>  
    </client>  
  </system.serviceModel>  
</configuration>  

另请参阅