WCF BasicHttpBinding 安全解析(1)BasicHttpBinding基本配置

BasicHttpBinding使用HTTP作为传输协议用于发送SOAP 1.1消息。服务可以使用此绑定来公开符合WS-I BP 1.1标准的终结点,如ASMX客户端访问的终结点。同样,客户端可以使用BasicHttpBinding与公开符合WS-I BP 1.1标准的终结点的服务(如 ASMX Web服务或采用BasicHttpBinding 配置的服务)进行通信。

默认情况下,安全性处于禁用状态,但是通过在BasicHttpBinding(BasicHttpSecurityMode)构造函数中将BasicHttpSecurityMode设置为不同于None的值,可以添加安全性。默认情况下,它使用“Text”消息编码和 UTF-8文本编码。

基于在11.2节我们使用的HelloService服务,我们这里使用BasicHttpBinding来对外发布它。

服务代码与之之前没有什么变化,如代码清单11-68。

代码清单11-68 HelloService服务

   1:  public class HelloService : IHelloService
   2:   
   3:      {
   4:   
   5:  public string GetHello()
   6:   
   7:          {
   8:   
   9:  if (ServiceSecurityContext.Current != null)
  10:   
  11:              {
  12:   
  13:  if (!ServiceSecurityContext.Current.IsAnonymous)
  14:   
  15:                  {
  16:   
  17:  return "Hello:" + ServiceSecurityContext.Current.PrimaryIdentity.Name + ";type="
  18:   
  19:                          + ServiceSecurityContext.Current.PrimaryIdentity.AuthenticationType;
  20:   
  21:                  }
  22:   
  23:  return "";
  24:   
  25:              }
  26:   
  27:  else
  28:   
  29:              {
  30:   
  31:  return "hello";
  32:   
  33:              }
  34:   
  35:          }
  36:   
  37:      }
  38:   

我们新建一个控制台项目,名为“basicHttpBindingHost”,用户做自定义宿主。宿主的配置如代码清单11-69。

代码清单11-69 服务宿主配置

   1:  <?xml version="1.0"?>
   2:   
   3:  <configuration>
   4:   
   5:    <system.serviceModel>
   6:   
   7:        <services>
   8:   
   9:        <service name="WcfSecurityExampleServiceLibrary.HelloService" behaviorConfiguration="mex" >
  10:   
  11:          <host>
  12:   
  13:            <baseAddresses >
  14:   
  15:              <add baseAddress="http://127.0.0.1:64567/"/>
  16:   
  17:            </baseAddresses>
  18:   
  19:          </host>
  20:   
  21:          <endpoint address="http://127.0.0.1:64567/HelloService" binding="basicHttpBinding"
  22:   
  23:  name="basicHttpHelloEndPoint"
  24:   
  25:  contract="WcfSecurityExampleServiceLibrary.IHelloService"  />
  26:   
  27:          <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"></endpoint>
  28:   
  29:        </service>
  30:   
  31:      </services>
  32:   
  33:      <behaviors>
  34:   
  35:        <serviceBehaviors>
  36:   
  37:          <behavior name="mex">
  38:   
  39:            <serviceMetadata/>
  40:   
  41:          </behavior>
  42:   
  43:        </serviceBehaviors>
  44:   
  45:      </behaviors>
  46:   
  47:    </system.serviceModel>
  48:   
  49:    <startup>
  50:   
  51:      <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
  52:   
  53:    </startup>
  54:   
  55:  </configuration>
  56:   

看代码清单11-69所示的配置,我们通过

   1:  <endpoint address="http://127.0.0.1:64567/HelloService" binding="basicHttpBinding"
   2:   
   3:  name="basicHttpHelloEndPoint"
   4:   
   5:  contract="WcfSecurityExampleServiceLibrary.IHelloService"  />

来设置当前终结点的绑定为basicHttpBinding,契约为WcfSecurityExampleServiceLibrary.IHelloService,并通过元数据终结点对外发布服务。宿主的代码如代码清单11-70所示。

代码清单11-70 服务宿主的实现

   1:  class Program
   2:   
   3:          {
   4:   
   5:  static void Main(string[] args)
   6:   
   7:              {
   8:   
   9:  ServiceHost hostForHello = new ServiceHost(typeof(HelloService));
  10:   
  11:                  hostForHello.Open(); 
  12:   
  13:  try
  14:   
  15:                  {
  16:   
  17:  while (true)
  18:   
  19:                      {
  20:   
  21:                      }
  22:   
  23:                  }
  24:   
  25:  catch
  26:   
  27:                  {
  28:   
  29:                      hostForHello.Abort();
  30:   
  31:                  }
  32:   
  33:              }
  34:   
  35:          }
  36:   

启动宿主程序,我们在浏览器中输入http://127.0.0.1:64567/,结果如图11-27。

clip_image002

图11-27 服务启动成功

从如11-27的结果我们可以看出服务启动成功并在指定端口监听。下面我们构造客户端,首先看客户端配置文件,如代码清单11-71。

代码清单11-71 客户端配置

   1:  <?xml version="1.0" encoding="utf-8" ?>
   2:   
   3:  <configuration>
   4:   
   5:    <system.serviceModel>
   6:   
   7:      <client>
   8:   
   9:             <endpoint address="http://127.0.0.1:64590/HelloService" binding="basicHttpBinding"
  10:   
  11:  contract="WcfSecurityExampleServiceLibrary.IHelloService" name="basicHttpHelloEndPoin"/>
  12:   
  13:      </client>
  14:   
  15:    </system.serviceModel>
  16:   
  17:  </configuration>

如代码清单11-71,客户端的配置很简单,只是指定终结点和契约,其他的配置采用默认配置。这里需要注意的是终结点指定的address=http://127.0.0.1:64590/HelloService,端口64590是我使用TcpTrace进行监听的端口,如图11-28。这里没有使用netTcpBinding在Behavior中设置的原因为BasicHttpBinding的AddressingVersion值为None,MessageVersion是不能改变的,只有CustomBinding才支持textMessageEncoding的设定。

clip_image004

11-28 tctTrace监听转发消息

客户端调用代码如代码清单11-72。

代码清单11-72 客户端调用代码

   1:  class Program
   2:   
   3:      {
   4:   
   5:  static void Main(string[] args)
   6:   
   7:          {
   8:   
   9:  using (ChannelFactory<IHelloService> channelFactory = new ChannelFactory<IHelloService>("basicHttpHelloEndPoint"))
  10:   
  11:              {
  12:   
  13:  IHelloService helloService = channelFactory.CreateChannel();
  14:   
  15:  using (helloService as IDisposable)
  16:   
  17:                  {
  18:   
  19:  Console.WriteLine(helloService.GetHello());
  20:   
  21:                  }
  22:   
  23:              }
  24:   
  25:  Console.Read();
  26:   
  27:          }
  28:   
  29:      }

调用代码和之前使用的并无差别,这里就不详说了。我们直接看运行结果,如图11-29。

clip_image006

图11-29 客户端运行结果

我们的服务返回的信息应该包含客户端用户名和验证类型,但是图11-29中没有这两项信息,原因在于默认情况下BasicHttpBinding不采用任何安全配置。我们再来看tcpTrace的监听结果,如图11-30。

clip_image008

图11-30 tcpTrace监听信息

从图11-30的监听结果来看,采用的是明文传输,编码格式为“text/xml”,没有任何认证和凭据信息。

一个完整的BasicHttpBinding的示例到这里演示完毕了,下面我们对它做进一步的分析。

posted @ 2011-06-27 12:56  玄魂  阅读(10476)  评论(3编辑  收藏  举报