用户名客户端的消息安全

下图显示了使用消息级别安全保护的 Windows Communication Foundation (WCF) 服务和客户端。 服务使用 X.509 证书进行身份验证。 客户端使用用户名和密码进行身份验证。

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

Message security using username authentication

特征 说明
安全模式 消息
互操作性 仅限 Windows Communication Foundation (WCF)
身份验证(服务器) 初始协商需要服务器身份验证
身份验证(客户端) 用户名/密码
完整性 是,使用共享安全上下文
机密性 是,使用共享安全上下文
Transport HTTP
绑定 WSHttpBinding

服务

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

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

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

代码

下面的代码演示如何创建使用消息安全的服务终结点。

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

// 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");

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.UserName

' 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")

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"
                                storeLocation="LocalMachine"  
                                storeName="My"
                                x509FindType="FindBySubjectName" />  
          </serviceCredentials>  
        </behavior>  
      </serviceBehaviors>  
    </behaviors>  
    <services>  
      <service behaviorConfiguration="ServiceCredentialsBehavior"  
               name="ServiceModel.Calculator">  
        <endpoint address="http://localhost/Calculator"  
                  binding="wsHttpBinding"  
                  bindingConfiguration="MessageAndUserName"  
                  name="SecuredByTransportEndpoint"  
                  contract="ServiceModel.ICalculator" />  
      </service>  
    </services>  
    <bindings>  
      <wsHttpBinding>  
        <binding name="MessageAndUserName">  
          <security mode="Message">
            <message clientCredentialType="UserName" />  
          </security>  
        </binding>  
      </wsHttpBinding>  
    </bindings>  
    <client />  
  </system.serviceModel>  
</configuration>  

客户端

代码

下面的代码创建客户端。 绑定设置为消息模式安全,客户端凭据类型设置为 UserName。 用户名和密码只能使用代码指定(不可配置)。 返回用户名和密码的代码未在此处显示,因为这必须在应用程序级完成。 例如,使用 Windows 窗体对话框查询用户以获得这些数据。

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

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

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

// Set the user name and password. The code to
// return the user name and password is not shown here. Use
// an interface to query the user for the information.
cc.ClientCredentials.UserName.UserName = ReturnUsername();
cc.ClientCredentials.UserName.Password = ReturnPassword();

// 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.UserName

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

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

' Set the user name and password. The code to
' return the user name and password is not shown here. Use
' an interface to query the user for the information.
cc.ClientCredentials.UserName.UserName = ReturnUsername()
cc.ClientCredentials.UserName.Password = ReturnPassword()

' 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

配置

下面的代码将配置客户端。 绑定设置为消息模式安全,客户端凭据类型设置为 UserName。 用户名和密码只能使用代码指定(不可配置)。

<?xml version="1.0" encoding="utf-8"?>  
<configuration>  
  <system.serviceModel>  
    <bindings>  
      <wsHttpBinding>  
        <binding name="WSHttpBinding_ICalculator" >  
          <security mode="Message">  
            <message clientCredentialType="UserName" />  
          </security>  
        </binding>  
      </wsHttpBinding>  
    </bindings>  
    <client>  
      <endpoint address="http://machineName/Calculator"
                binding="wsHttpBinding"  
                bindingConfiguration="WSHttpBinding_ICalculator"
                contract="ICalculator"  
                name="WSHttpBinding_ICalculator">  
        <identity>  
          <dns value ="Contoso.com" />  
        </identity>  
      </endpoint>  
    </client>  
  </system.serviceModel>  
</configuration>  

另请参阅