WCF 错误:“X.509 证书 CN=localhost 链构建失败......”

Posted

技术标签:

【中文标题】WCF 错误:“X.509 证书 CN=localhost 链构建失败......”【英文标题】:WCF error: "The X.509 certificate CN=localhost chain building failed ..." 【发布时间】:2011-05-14 11:31:00 【问题描述】:

我在尝试使我的 WCF 客户端和服务器相互通信时遇到此错误。

X.509 证书 CN=localhost 链构建失败。这 使用的证书具有无法验证的信任链。 更换证书或更改 certificateValidationMode。一种 证书链已处理,但在根证书中终止 不受信任的信任。

如果我关闭 SSL 证书,一切都会完美运行。

【问题讨论】:

【参考方案1】:

我通过在我的代码中关闭验证来解决问题,如下所示:

client.ClientCredentials.ServiceCertificate.Authentication.CertificateValidationMode = 
System.ServiceModel.Security.X509CertificateValidationMode.None;

client 是我的服务引用的一个实例。

【讨论】:

这对我也有用,改变 web.config 没有。请注意,这绝不应该进入您的生产环境! 必须将引用“System.IdentityModel”添加到客户端项目以使其编译 X509CertificateValidationMode 枚举位于 System.IdentityModel 程序集中。这很令人困惑,因为 X509ServiceCertificateAuthentication 类似乎位于 System.ServiceModel.dll 中。【参考方案2】:

您的证书有问题(我想您使用自签名证书) WCF 尝试验证所有颁发者链并期望,最终链将在根受信任的权限上结束。要禁用该检查,您可以将这样的行添加到 app.config 分支。但是这个“拐杖”不应该在生产中使用serviceBehaviors/behavior/serviceCredentials/clientCertificate

【讨论】:

太好了,现在可以完美运行了。你是对的,我使用的是自签名证书。修复此错误的另一个关键技巧是使用 Microsoft 服务配置编辑器在 app.config 中将“NegotiateServiceCredential”切换为“false”。 请原谅我的无知——这条线应该放在客户端还是服务器端?在 app.config 的哪个部分? @Shaul 部分是 serviceBehaviors/behavior/serviceCredentials/clientCertificate 您应该将此添加到服务器的 app.config 这对我没有任何帮助。我有同样的问题。添加了配置值,并没有改变任何东西。 我解决了在客户端配置文件 (app.config) 上添加端点行为和在 serverCertificate 上将 CertificateValidationMode 设置为 None 的问题。不要忘记在端点主配置上引用 Endpoint Behavior 以考虑该行为【参考方案3】:

正确的做法是setup your own Dev/Test Trusted Root Certificate 并用它签署您的客户端和服务证书。

在您的开发/测试环境中绕过链信任可能“有效”,但您的开发/测试环境现在与生产环境的配置不同,这不是一个好主意,因为您可能会发现某些测试会产生误报或误报。

【讨论】:

【参考方案4】:

在您的客户端应用程序中添加端点行为(例如:App.config)并设置您在端点中添加的行为配置。

 <behaviors>
          <endpointBehaviors>
            <behavior name="certificateEndpointBehavior">
              <clientCredentials>
                <serviceCertificate>             
                  <authentication certificateValidationMode="None" revocationMode="NoCheck"/>
                </serviceCertificate>
                </clientCredentials>      
            </behavior>
          </endpointBehaviors>
        </behaviors>

<endpoint address="http://localhost/Invoice.svc" binding="wsHttpBinding"  bindingConfiguration="WsHttpBinding_ACKS" contract="Invoice" name="Invoice"
       behaviorConfiguration="certificateEndpointBehavior" >

</endpoint>

【讨论】:

这是正确的解决方案。您甚至无需担心设置“certificateValidationMode”。只需要撤销模式。在服务器端设置值不起作用。在代码中破解每个客户端端点的工作量太大了。【参考方案5】:

我在同样的问题上遇到了一些困难。我使用的是 WIF SDK 中的 CustomToken-VS2010 示例。

该示例没有 app.config,我觉得无论如何了解代码的工作原理很有用,因此我花了一些时间对此进行调查。我觉得我应该在这里展示我的结果。我希望这些信息对您有所帮助。

我有同样的问题。我遇到的问题是“我在哪里设置这个模式?”我很难找到要设置此属性的对象,它实际上是正确的对象。我终于发现它是 ChannelFactory 的一部分:

using System.ServiceModel.Security;
:
ChannelFactory<IEcho> echoChannelFactory = new ChannelFactory<IEcho>(...)
echoChannelFactory.Credentials.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None;

所以,设置它的地方是在 ChannelFactory 对象中。

以本地管理员身份运行 Visual Studio 2010,我能够让示例工作(在还运行与所有示例关联的批处理文件以创建证书等之后)

再次重申,这不是你在生产环境中会做的事情,但是知道如何设置服务证书身份验证模式可能是一个很好的整体了解.

【讨论】:

是否应该使用 ChannelFactory&lt;TChannel&gt;.CredentialsClientBase&lt;TChannel&gt;.ClientCredentials 取决于您是显式使用通道工厂(使用动态代理)还是由某些代码生成器创建的生成代理(例如,通过添加通过 VS-GUI 提供服务参考)。【参考方案6】:

当停用 revocationMode 有帮助时,您很可能缺少根 CA 的客户端吊销列表

makecert -crl -n "CN=CARoot" -r -sv CARoot.pvk CARoot.crl

这也需要导入到受信任的根证书颁发机构。另见my answer here。

【讨论】:

【参考方案7】:

(以为我会分享这个以防万一它可以节省一些时间)我在 WIF 上运行 Web 应用程序时遇到了这个问题。我通过将我正在使用的 x.509 证书的副本从“证书/个人/证书”文件夹移动到证书存储中的“受信任的根证书颁发机构/证书”文件夹来解决了我的问题。你可以通过运行微软管理控制台来做到这一点

【讨论】:

【参考方案8】:

根据上面 Aseiu 的评论,我发现当服务器中的受信任存储中缺少证书时,会输出与上面完全相同的错误。在研究这个问题时,我还发现通过查看 Windows 日志/应用程序下的事件查看器将包含一个错误,详细说明它有问题的证书。您还可以将活动日志与服务的 SVC 日志中的条目相关联。

【讨论】:

以上是关于WCF 错误:“X.509 证书 CN=localhost 链构建失败......”的主要内容,如果未能解决你的问题,请参考以下文章

WCF 错误:相对端点地址

WCF 错误处理

如何使用故障契约和 jquery ajax 处理 wcf 错误

WCF 显示超时错误

WCF + JSONP:总是收到“方法不允许”错误消息

处理代理中的错误 - WCF