如果没有本地计算机上的服务器证书,客户端WCF无法连接到服务器WCF

时间:2012-03-23 14:48:51

标签: wcf ssl certificate client-server x509

场景是这样的:有2个WCF Web服务,一个是客户端(WCFClient),一个是服务器(WCFServer),部署在不同的机器上。我需要他们两人之间的证书沟通。

在服务器WCF上,我已将绑定设置为使用证书作为客户端凭据类型。

<security mode="Message">
      <message clientCredentialType="Certificate" />
</security>

此外,在行为部分,除其他设置外,我还有

<serviceBehaviors>
      <behavior name="Server.ServiceBehavior">                  
          <serviceCredentials>
            <clientCertificate>
              <authentication certificateValidationMode="PeerTrust"/>
            </clientCertificate>
            <serviceCertificate findValue="Server"
            storeLocation="LocalMachine"
            storeName="TrustedPeople"
            x509FindType="FindBySubjectName" />
          </serviceCredentials>
        </behavior>
</serviceBehaviors>

在客户端WCF服务上,我添加了此端点行为

<endpointBehaviors>
   <behavior name="CustomBehavior">
     <clientCredentials>
       <clientCertificate findValue="Client" 
                          x509FindType="FindBySubjectName" 
                          storeLocation="LocalMachine" 
                          storeName="TrustedPeople" />
       <serviceCertificate>            
         <authentication certificateValidationMode="PeerTrust"/>
       </serviceCertificate>
     </clientCredentials>
   </behavior>
 </endpointBehaviors>

当我想测试我的服务时,我收到了一条错误消息:

The service certificate is not provided for target 'http://blablabla...'. Specify a service certificate in ClientCredentials.

所以我开始在互联网上查看。在尝试了很多东西之后,唯一真正有效的是在我的客户端上添加它:

<serviceCertificate>
         <defaultCertificate findValue="Server"
                             storeLocation="LocalMachine"
                             storeName="TrustedPeople"
                             x509FindType="FindBySubjectName" />
         <authentication certificateValidationMode="PeerTrust"/>
       </serviceCertificate>

您可能认为,是的,这意味着我需要在客户端计算机上使用服务器证书。这显然是一件非常糟糕的事情。 它适用于我的测试目的,但是部署是不可接受的。

我想了解真正导致该错误消息的原因以及解决方案可能是什么。

稍后编辑:在此项目中,客户端必须没有服务器证书(即使没有私钥)。这是系统的规范,而且(以bureaucracy术语)超出此范围是非常困难的。 将有多个客户端,每个客户端都运行客户端WCF服务,每个客户端应该只知道自己的证书。服务器将知道服务器证书和所有客户端证书。

3 个答案:

答案 0 :(得分:3)

查看here

  

在考虑身份验证时,您可能习惯于主要思考   客户身份。但是,在WCF的上下文中,身份验证   通常是指相互认证。相互认证不是   只允许客户的正面识别,但也允许   客户可以肯定地识别它们所属的WCF服务   连接的。相互认证尤为重要   面向Internet的WCF服务,因为攻击者可能会欺骗   WCF服务并劫持客户端的调用以显示   敏感数据。

     

要使用的服务凭据主要取决于客户端   您选择的身份验证方案通常,如果您正在使用   非Windows客户端身份验证,例如用户名或证书   身份验证,服务证书用于这两种服务   身份验证和消息保护。如果您使用的是Windows客户端   身份验证,进程标识的Windows凭据即可   用于服务身份验证和邮件保护。

在我看来,你需要客户机上的服务器证书,这是一件好事,不是坏事。请注意,您在客户端计算机上需要(并且不应该)服务器的私钥。私钥不包含在证书中 - 只有公钥是。

在客户端计算机上拥有服务器证书意味着只在客户端计算机上拥有服务器的公钥。好处是客户现在知道它正在与真实服务器通信。

我不熟悉WCF服务,但就证书的使用而言,这似乎很好。

答案 1 :(得分:1)

为什么在客户端计算机上安装服务证书不好?它只是公共部分,而不是私钥。

如果使用wshttpbinding,则可以设置negotiateServiceCredential = true,在这种情况下,客户端将动态获取服务器证书。价格有点受到性能影响,这个端点不能与非.net客户端互操作。

答案 2 :(得分:0)

我实际上忘记了这个问题,但当时我找到了解决方案。

我的实际问题是我使用basicHttpBinding进行我想要保护的通信。 basicHttpBinding意味着使用serviceCredential部分。 http://msdn.microsoft.com/en-us/library/ms731338(v=vs.85).aspx

由于我的系统要求,我将绑定更改为wsHttpBinding。现在我不需要将服务器证书放在客户端计算机上。