为什么WCF会抱怨身份验证失败?

21
我正在创建一个WCF应用程序,将使用证书对客户端和服务器之间的通信进行加密。在开发环境中,我想使用一个测试证书/自签名证书,该证书是使用makecert创建的(只有服务器会有证书,客户端不会)。
我已将证书安装到证书存储中,并且一切正常。在客户端上,certificateValidationMode当前设置为“false”,因为我正在使用测试证书。
我的问题:
在客户端的app.config中,我需要将identity元素指定为以下内容:
<endpoint ... >
   <identity>
      <dns value="<Name-Of-Server-Computer>"/>
   </identity>
</endpoint>
如果我删除身份元素,则在尝试连接到服务器时客户端会显示以下错误消息:
“传出消息的标识检查失败。远程端点的预期DNS标识为'localhost',但是远程端点提供了DNS声明'Name-Of-Server-Computer'。如果这是合法的远程端点,则可以通过在创建通道代理时显式指定DNS标识'Name-Of-Server-Computer'作为Identity属性来解决问题。”
因此,我的问题如下:
1. 当使用真实、受信任的从CA购买的证书部署应用程序时,标识检查是否仍然会进行?或者只有在使用测试/自签名证书时才会执行标识检查?
2. 是否有方法禁用身份检查?我知道可以创建自己的自定义证书验证器,但似乎没有办法使用这些覆盖身份检查。
3个回答

32

这个问题的答案已经在错误信息里了。在客户端你可以做如下操作:

EndpointIdentity identity = EndpointIdentity.CreateDnsIdentity("Server");
EndpointAddress address = new EndpointAddress(new Uri("net.tcp://1.2.3.4:12345/ServiceName"), identity);

将 "Server" 替换为您预期的内容。通常这将是自签名证书的公共名称 (CN)。 这样做不会破坏安全性,前提是您承担所有责任,确保呈现的证书是有效的,也就是创建您自己的自定义证书验证器,并进行相关检查。


11

检查总是会进行 - 而且应该如此。基本上,WCF将检查证书是否颁发给服务所在的域名(yourcompany.com)或机器名。这是一个安全检查,我永远不会禁用!否则,冒充您的服务的任何人都可以使用任意颁发给任意域名/机器名的证书来获取您的流量 - 这不是您想要的!

因此,您需要确保生产服务器上的真实证书确实是颁发给生产服务器将成为其中一部分的域名,例如如果您的生产服务器将位于“production.yourcompany.com”,则证书需要颁发给该域。

Marc


“这是一个安全检查,我永远不会禁用!” - Nitramk
1
我从未考虑过这样做,因此我从未感到有必要检查是否有关闭它的方法。抱歉,我不知道。 - marc_s

4

certificateValidationMode应该设置为“None”,而不是“false”...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接