基本身份验证似乎没有安全标头

时间:2017-02-06 12:04:03

标签: c# wcf fiddler basic-authentication

我编写了一个非常简单的WFCSerice,它返回提供的Windows用户名。这是客户端代码:

public Form1()
        {
            ServiceReference1.Service1Client s1 = new ServiceReference1.Service1Client();
            s1.ClientCredentials.Windows.ClientCredential = System.Net.CredentialCache.DefaultNetworkCredentials;
            string str = s1.ReturnWindowsUsername();
            InitializeComponent();
        }

我可以使用Fidddler看到HTTP标头中的凭据:

enter image description here

我尝试使用基本身份验证(访问支持基本身份验证的其他Web服务)执行相同的操作。这是客户端代码:

public Form1()
        {
            InitializeComponent();
            ServiceReference1.Service1Client s1 = new ServiceReference1.Service1Client();
            s1.ClientCredentials.UserName.UserName = "testuser";
            s1.ClientCredentials.UserName.Password = "testpassword";
            string str = s1.GetData(1);

        }

以下是使用基本身份验证时Fiddler的屏幕截图:

enter image description here

使用基本身份验证时,为什么标头中没有任何内容。基本身份验证服务似乎按预期工作。这是响应(有趣的是,似乎有两个请求和两个响应):

enter image description here

1 个答案:

答案 0 :(得分:1)

基本身份验证适用于HTTP级别。一般流程是客户端请求资源,然后服务器发出质询,然后客户端发出包含Authorization标头的新请求。如果服务器接受Authorization标头中的用户名和密码,则客户端通常会为后续请求添加标头,而无需再次执行request - challenge - re-request-with-authorization步骤。

如果您正确设置了所有内容,您应该会在Fiddler中看到两个请求。

  1. 包含Authorization标头的一个请求。服务器对此请求的响应为401,附加WWW-Authenticate: Basic realm="your realm"标头。
  2. 然后您应该看到第二个请求,其中已从客户端发送Authorization标头。
  3. 以下是我的环境中的示例:

    enter image description here

    如果您没有从服务器看到401质询,则说明基本身份验证设置不正确。

    要使服务代理提供标头,您需要将客户端绑定配置为使用<transport clientCredentialType="Basic"/>。或者这就是我所做的,谁知道WCF有无数的配置选项。

    编辑:我在服务方面使用了这个:

    <bindings>
      <basicHttpBinding>
        <binding name="httpTransportCredentialOnlyBinding">
          <security mode="TransportCredentialOnly">
            <transport clientCredentialType="Basic" />
          </security>
        </binding>
      </basicHttpBinding>
    </bindings>
    

    在客户端:

    <bindings>
      <basicHttpBinding>
        <binding name="BasicHttpBinding_IService1">
          <security mode="TransportCredentialOnly">
            <transport clientCredentialType="Basic"/>
          </security>
        </binding>
      </basicHttpBinding>
    </bindings>
    <client>
      <endpoint address="http://localhost:53156/Service1.svc" binding="basicHttpBinding"
        bindingConfiguration="BasicHttpBinding_IService1" contract="WcfTest_CBT.IService1"
        name="BasicHttpBinding_IService1" />
    </client>
    

    我使用basicHttpBindingTransportCredentialOnlyBasic来轻松测试,无需SSL麻烦等。