【问题标题】:Basic Authentication appears to have no security header基本身份验证似乎没有安全标头
【发布时间】:2017-02-06 12:04:02
【问题描述】:

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

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

我可以使用 Fiddler 在 HTTP 标头中查看凭据:

我尝试对基本身份验证做同样的事情(访问另一个支持基本身份验证的 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 在使用基本身份验证时的屏幕截图:

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

【问题讨论】:

  • 您是否禁用了匿名身份验证,并在 IIS 中启用了基本身份验证? Authorization 标头仅在来自服务器的 401 质询之后添加到请求中。如果允许匿名请求,则没有 401,因此不需要标头。
  • @user1429080,两者都已启用。
  • 尝试禁用匿名身份验证。有区别吗?
  • @user1429080,如果我这样做,则会引发以下异常: System.ServiceModel.Security.MessageSecurityException:附加信息:HTTP 请求未经客户端身份验证方案“匿名”授权。从服务器收到的身份验证标头是 'Basic realm=mydomain.mypc.local.
  • 请求的“trace”在 Fiddler 中是怎样的?应该有来自服务器的 401 响应,然后是来自客户端的带有标头的新请求。如果您收到 404,则用户名/密码组合无效。

标签: c# wcf fiddler basic-authentication


【解决方案1】:

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

如果一切设置正确,您应该会在 Fiddler 中看到两个请求。

  1. 一个不包含Authorization 标头的请求。服务器对此请求的响应将是一个带有WWW-Authenticate: Basic realm="your realm" 标头的401
  2. 然后您应该会看到第二个请求,其中已从客户端发送了 Authorization 标头。

这是我的环境中的一个示例:

如果您没有看到来自服务器的 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 麻烦等。

【讨论】:

  • 谢谢。我已经尝试过你的建议。标题中仍然没有安全性。基本身份验证正常工作,但是,我完全不知道凭据是如何传递到服务器的。
  • 不,我没有。是否必须是 BasicHttpBinding 才能在标头中传递凭据?我的研究告诉我,凭据是使用 wsHttpBinding 在 SOAP 消息(加密)中传递的。我对此很陌生。
  • 使用什么绑定?什么是安全模式?
  • 再次感谢。我有这些设置,现在我无法更新我的服务参考。它说:“服务器需要验证您的请求。您的凭据将以明文形式发送。您要继续吗?”有什么想法吗?
  • 谢谢。它不接受我的基本身份验证凭据。它只是不断提示我。
猜你喜欢
  • 2015-11-19
  • 2015-08-08
  • 1970-01-01
  • 2015-03-13
  • 1970-01-01
  • 2019-02-21
  • 1970-01-01
  • 2018-09-07
  • 1970-01-01
相关资源
最近更新 更多