代码改变世界

关于应用WCF X.509证书验证的小结(转)

2010-03-12 12:19  Vincent.Feng  阅读(637)  评论(0编辑  收藏  举报

转自:   http://www.cnblogs.com/dreamtrue/archive/2008/07/05/1235991.html

 最近在配WCF X.509证书验证,我想在服务端实现SSL加密,然后当客户端调用服务时,需要出示自己的数字证书以证明自己是合法的用户。
    配置过程很麻烦,不像书上说的那样。我总结了一下有如下几点需要注意
   
    在IIS部分,对于有服务器证书的WCF服务站点,可以要求SSL连接,128位加密,但是不能要求客户端证书。
    在WCF服务部分,不能使用wsDualHttpBinding,应为它一个通道SSL,另一个通道不能保证安全,在服务运行时会抱错。

    配置过程大致有以下几步:
    1。配置IIS SSL服务器证书
    2。获取并设置客户端证书
    3。配置WCF的服务端和客户端

    上述第1步,涉及到IIS的应用,不是本文重点,相信玩过IIS和证书颁发机构的朋友都不陌生,不做叙述了。第2步的中获取证书也是比较容易的,配置证
    书就比较麻烦,新证书一般默认安装到本机的Current_User\My下,非系统管理员无法获取其私钥,而WCF客户端又需要获取该证书私钥以向服务端证明
    自己的身份,而且WCF客户端运行时使用的是非本机管理员帐号,这就导致了WCF会报出无法找到证书的错误。解决这个问题,我们需要使用名为
   “Windows HTTP 服务证书配置工具”(WinHttpCertCfg.exe) 的工具为证书指定权限。该工具包含在Windows Server 2003 Resource Kit Tools
    可以到微软下载,地址是:http://www.microsoft.com/downloads/details.aspx?FamilyID=9d467a69-57ff-4ae7-96eeb18c4790cffd&displaylang=en
    下载好后在命令行类似下面的命令
        WinHttpCertCfg.exe -g -c CURRENT_USER\MY -s "Issued_To_name" -a DOMAIN\account 
    就是说给account帐号赋予获取私钥的权限,可用ASPNET,NETWORKSERVICE等,-s后面是要搜索的条件
    具体的WinHttpCertcfg.exe的用法麻烦大家到网上查查,我查到过一篇MSDN的文档,但链接地址忘记保存(汗。。。。)
 在分配完权限后,最好关掉IIS的进程,这样设置生效比较快 ,同样我们也需要配置服务所需的证书。
  做完了第2步,第3步就好办了,贴一下我的配置
    
  服务端
  


 1    <behaviors>
 2      <serviceBehaviors>
 3        <behavior name="MemberServiceBehavior">
 4          <serviceMetadata httpGetEnabled="false" httpsGetEnabled="true">
 5          <serviceDebug includeExceptionDetailInFaults="false"/>
 6          <serviceCredentials>
 7            <serviceCertificate  storeName="My" storeLocation="LocalMachine" x509FindType="FindBySubjectName" 
 8                                 findValue="membershipapi"/>
 9          </serviceCredentials>
10        </behavior>
11      </serviceBehaviors>
12    </behaviors>

 


 1    <bindings>
 2      <wsHttpBinding>
 3        <binding name="wsHttpCredentialBinding">
 4          <security mode="TransportWithMessageCredential">
 5            <transport  clientCredentialType="Certificate"/>
 6            <message clientCredentialType="Certificate" />
 7          </security>
 8        </binding>
 9      </wsHttpBinding>
10    </bindings>

  客户端


 1      <behaviors>
 2        <endpointBehaviors>
 3          <behavior name="clientCredentialBehavior">
 4            <clientCredentials>
 5              <clientCertificate  storeName="My" storeLocation="CurrentUser" findValue="MemberApiClient"  x509FindType="FindBySubjectName" />
 6              <serviceCertificate>
 7                <authentication   certificateValidationMode="ChainTrust"/>
 8              </serviceCertificate>
 9            </clientCredentials>
10          </behavior>
11        </endpointBehaviors>
12      </behaviors>


我这样的配置虽然客户端在不提供证书的情况下仍然能够看到服务的元数据终结点(主要是因为IIS没有配置为要求客户端证书),但是在调用服务时
如果没有证书,就会抱错,目的基本达到。
最后我想说一下,书上讲authentication certificateValidationMode配置为PreeTrust比较好,只要在信任的人的列表里就可以通过验证,可是经过我的试验
似乎不是这样,在我的客户端和服务中,authentication certificateValidationMode值配置为PreeTrust或ChainTrust没有什么区别,客户端都需要将证明
自己的证书找出来,提供给服务,不然就要抱错。后来我在MSDN找到一段文字是这样解释的:
 
    <endpointBehaviors>
      <behavior name="ClientCertificateBehavior">
        <!--
      The clientCredentials behavior allows you to define a certificate to present to a service.
      A certificate is used by a client to authenticate itself to the service and provide message integrity.
      This configuration references the "client.com" certificate installed during the setup instructions.
      -->
        <clientCredentials>
          <clientCertificate findValue="client.com" storeLocation="CurrentUser" storeName="My" x509FindType="FindBySubjectName" />
          <serviceCertificate>
            <!--
          Setting the certificateValidationMode to PeerOrChainTrust means that if the certificate
          is in the user's Trusted People store, then it is trusted without performing a
          validation of the certificate's issuer chain. This setting is used here for convenience so that the
          sample can be run without having certificates issued by a certificate authority (CA).
          This setting is less secure than the default, ChainTrust. The security implications of this
          setting should be carefully considered before using PeerOrChainTrust in production code.
          -->
            <authentication certificateValidationMode="PeerOrChainTrust" />
          </serviceCertificate>
        </clientCredentials>
      </behavior>
    </endpointBehaviors>

看来有时候还是要看看英文,才能学好WCF。。。。。

更新:根据jillzhang的说法,并加以验证,确实只要将证书放到LocalMachine中,不需要WinHttpCertCfg.exe 配置,WCF就能找到,不会抱无法找到证书错误,谢谢jillzhang。

 

IIS配置证书(参考)

http://www.cnblogs.com/mikespook/archive/2004/12/22/80591.html

http://www.cnblogs.com/luohuarenduli/archive/2008/01/18/1044918.html