配置WCF服务以使用X509证书对服务器进行身份验证,但不使用服务器凭据

时间:2012-03-24 18:57:34

标签: wcf security x509certificate

我开发了一个ASP.NET MVC网站,它也托管了一个WCF 4服务;我创建了一个.NET Windows应用程序,它补充了网站,并通过互联网消费该Web服务与之交互。这两个程序都是在Visual Studio 2010中使用.NET 4创建的。与WCF服务一起使用的绑定是WsHttpBinding。

我的安全要求是某个未知方不会使用WCF服务,因为这会污染我网站数据库中的信息。我不需要任何隐私:我不在乎某些第三方是否看到我发送给Web服务的消息(即,不需要加密)

考虑到单一要求,并且就我对Web服务安全性的了解而言,实现该安全方案的最佳方式是客户端使用X509证书对每个SOAP消息进行签名,并使Web服务信任使用“受信任的人”商店中存在的证书签署的任何邮件。由于证书使用公钥/私钥对,即使邮件未加密,如果没有用于签名邮件的私钥,也不能由未经授权的第三方复制。这也可以保证信息的完整性。

考虑到这个决定,我使用makecert.exe创建了一个测试证书。我在“当前用户”“我的”证书存储区中安装了两者客户端计算机中的私钥和公钥(带有Windows应用程序的那个)的版本。然后,我导出了证书(没有私钥),并将其安装在Web服务器的“本地机器”证书存储的“可信人员”中。

到目前为止我的(不成功)尝试配置该场景的方式如下:

绑定配置为使用Message安全性,其中Message需要证书类型的客户端凭据。此外,服务器配置为使用PeerTrust而不是ChainTrust,因为受信任的CA不会发出测试证书:

<bindings>
  <wsHttpBinding>
    <binding>
      <security mode="Message">
        <transport clientCredentialType="None" proxyCredentialType="None" />
        <message clientCredentialType="Certificate" />
      </security>
    </binding>
  </wsHttpBinding>
</bindings>

<behaviors>
  <serviceBehaviors>
    <behavior name="Standard">
      <serviceMetadata httpGetEnabled="true" />
      <serviceDebug includeExceptionDetailInFaults="true" />
      <serviceCredentials>
        <clientCertificate>
          <authentication certificateValidationMode = "PeerTrust" trustedStoreLocation="LocalMachine"/>
        </clientCertificate>
      </serviceCredentials>
    </behavior>
  </serviceBehaviors>
</behaviors>

客户端Windows应用程序上的配置将证书设置为其凭据。绑定配置与服务器中的绑定配置相同。

<behaviors>
  <endpointBehaviors>
    <behavior name="CertificateCredential">
      <clientCredentials>
        <clientCertificate findValue="ErrEye"
                           storeLocation="CurrentUser"
                           storeName="My"
                           x509FindType="FindBySubjectName" />
      </clientCredentials>
    </behavior>
  </endpointBehaviors>
</behaviors>

问题是,使用此配置,当我尝试检查Web服务主机是否已成功启动时,出现以下错误:

The service certificate is not provided. Specify a service certificate in ServiceCredentials.

我的问题是,我不想指定“服务证书”。据我所知,服务证书将允许客户端验证服务,但我不需要;我只是希望服务验证客户端,就是这样。我理解这意味着如果有人冒充Web服务器(例如通过篡改我的客户端计算机的DNS设置),它会收到来自我的客户端的消息,而客户端不会知道它不是与目标收件人沟通:我不介意是否会发生这种情况。

总之,我的问题是:如何在WCF中配置我所描述的安全方案?

提前感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

只要.net到.net(并且仍然如此) - 添加此

negotiateServiceCredential=true

为:

<message clientCredentialType="Certificate" />

但要注意,您将失去与非.net客户端的互操作性。