"根据验证程序"远程证书无效。使用HttpClient

时间:2015-12-18 11:16:43

标签: c# ssl-certificate dotnet-httpclient

无法通过证书验证解决问题。

有Web API服务器,它使用HTTPS来处理请求。服务器的证书具有此证书路径:RCA(root) - > ICA(中间) - > Web API服务器。 RCA,ICA和Web API服务器是同一Active Directory域的成员。

客户端应用程序(桌面,计算机加入同一域)使用HttpClient与服务器通信并支持两种方案:

  • 连接到公司网络;
  • 与公司网络断开连接(互联网访问)。

两种情况都使用基本身份验证 RCA和ICA证书放在"受信任的根证书颁发机构"和#34;中级证书颁发机构"分别用于本地计算机帐户。 RCA证书是自签名的。

现在,当客户端连接到公司网络时,证书验证按预期工作,用户可以"通话"到Web API。

当客户端断开连接(只有Internet连接可用)时,证书验证将失败并显示AuthenticationException("根据验证程序&#34,远程证书无效)。

我不想完全关闭证书验证,但只需要告诉验证系统,这个特定的证书是有效的。 此外,客户端应用程序使用SignalR,它默认使用它自己的传输。因此,thisthis不是选项。

为什么将RCA ICA证书放入"信任......"和"中级......"文件夹没有帮助?

有解决方法吗?

3 个答案:

答案 0 :(得分:3)

您遇到的问题是因为证书提供的主题CN与Uri中的主机名不匹配。

确保绑定到主机公共IP地址的证书与您用于访问资源的主机名具有匹配的CN。

要轻松验证,请在浏览器中打开Url并查看证书。 颁发给字段应包含FQDN并匹配Uri中的主机名部分。在你的情况下,它没有。

答案 1 :(得分:1)

在程序正文中插入这段代码:

static void Main(string[] args)   
{
     ServicePointManager.ServerCertificateValidationCallback =
                delegate (object sender, X509Certificate certificate, X509Chain 
     chain, SslPolicyErrors sslPolicyErrors)
                {
                    return true;
                };
     ....
}

答案 2 :(得分:1)

不幸的是,至少在SignalR 3.1客户端中,@ Qosai的答案对我来说还不够,因为websocket部分还可以验证SSL证书。 ClientCertificateOptions也需要设置为“手动”。

我找到了SignalR贡献者的post,让我开始工作:

_connection = new HubConnectionBuilder()
            .WithUrl(new Uri(hub_uri), options => {
                options
                    .Cookies
                    .Add(http_helper.loginCookie);

                var handler = new HttpClientHandler
                {
                    ClientCertificateOptions = ClientCertificateOption.Manual,
                    ServerCertificateCustomValidationCallback = (httpRequestMessage, cert, cetChain, policyErrors) => true
                };
                options.HttpMessageHandlerFactory = _ => handler;
                options.WebSocketConfiguration = sockets =>
                {
                    sockets.RemoteCertificateValidationCallback = (sender, certificate, chain, policyErrors) => true;
                };
            })
            .Build();

PS:如果仍然有问题,请查看此article,了解如何正确启用日志记录。就我而言,这有点棘手,因为xUnit不显示控制台输出。因此,我启用了调试记录到文件的功能(不在代码段中)