.NET 客户端连接到 ssl Web API

Posted

技术标签:

【中文标题】.NET 客户端连接到 ssl Web API【英文标题】:.NET client connecting to ssl Web API 【发布时间】:2013-03-04 16:06:51 【问题描述】:

我有一个想与 ssl 一起使用的 ASP.NET Web API。当前服务器正在使用自签名证书,此时允许使用 http 和 https。我有一个非常基本的测试客户端,它适用于 http,但不适用于 https。我想知道如何修改下面的客户端代码,以便它可以与 https 一起使用。目前 IE、Firefox 和 Chrome 都可以使用 http 和 https(带有证书警告)连接到 Web API,所以这让我相信我不应该修改服务器上的任何内容,只需在客户端代码中。这是客户端代码:

static void Main(string[] args)

    try
    
        if (args.Length != 1)
        
            Console.WriteLine("Please provide a url, and only a url.");
            return;
        

        var url = new Uri(args[0]);
        var urlAuthority = url.GetLeftPart(UriPartial.Authority);
        var urlPathQuery = args[0].Substring(urlAuthority.Length);
        HttpClient client = new HttpClient();
        client.BaseAddress = new Uri(urlAuthority);
        HttpResponseMessage response = client.GetAsync(urlPathQuery).Result;
        if (response.IsSuccessStatusCode)
            Console.WriteLine(response.Content.ReadAsAsync<string>().Result); // expecting scalar results only
        else
            Console.WriteLine("0 (1)", (int)response.StatusCode, response.ReasonPhrase);
    
    catch (Exception ex)
    
        Exception tempEx = ex;
        while (tempEx != null)
        
            Console.WriteLine(tempEx.Message);
            tempEx = tempEx.InnerException;
        
    

当我使用我的 http url 运行上述代码时,它工作正常。当我将 url 更改为 https 时,会打印以下错误:

One or more errors occurred.
An error occurred while sending the request.
The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel.
The remote certificate is invalid according to the validation procedure.

我的一个问题是客户端是否必须手动向服务器发送公钥以便它知道如何发回加密响应,或者这是否会在幕后自动发生?其次,现在在看到最后一个错误之后,我想知道我是否还必须在客户端内执行其他操作来忽略证书警告并相信该证书可以继续进行?

【问题讨论】:

您的配置中是否将安全模式设置为传输? 另一个例子可以在这里找到:***.com/a/42449178/112397 【参考方案1】:

查看C# Ignore certificate errors SO 问题。我相信您可以使用 ServicePointManager 添加证书验证处理程序来规避证书验证。不过,在生产环境中使用签名证书可能是个好主意。

ServicePointManager
    .ServerCertificateValidationCallback += 
    (sender, cert, chain, sslPolicyErrors) => true;

【讨论】:

我同意在 prod 中使用签名证书,尽管在这种情况下,我们的 prod Web API 不会公开,因为它只是从我们控制下的自动化客户端连接,但它仍然是通过互联网,这就是我们首先需要 SSL 的原因。 我有 2 点,1. 这个解决方案需要 Dev 和 Prod 环境之间的代码差异。我的意思是 Prod 不需要此代码,它会忽略证书错误。 2. 这是应用程序/语言特定的修复。如果 jquery AJAX 请求需要访问这个 API 怎么办。在我看来,正如@Devin 所提到的,自签名证书应该在开发机器上通过提升为根证书来获得信任。请参阅此链接,该链接使用 IIS Express 和 SSL 设置开发环境而不会发出警告hanselman.com/blog/…【参考方案2】:

这对我有用。只需在调用 GetAsync 之前添加以下内容。

ServicePointManager.ServerCertificateValidationCallback = delegate  return true; ;

这将忽略 SSL 错误。仅建议在内网环境或其他无法伪造服务器身份的封闭网络中使用。

【讨论】:

非常适合在开发中测试 API。谢谢。【参考方案3】:

此错误消息表示客户端在 SSL 握手期间不信任服务器证书。有些浏览器更宽容一些,会给你一个“红条”,但从代码调用会导致 401 和被拒绝的调用。

您不需要对 IIS 中的客户端证书设置做任何事情(因为我假设您没有使用客户端证书)。

此异常消息告诉您在客户端验证时自签名证书链被拒绝。您可能会通过导出(不带私钥)自签名证书并将其作为根证书安装在客户端计算机上来解决此问题。

如果这不起作用,您需要制作一个新的 CA(证书颁发机构证书),然后生成一个与 CA 签署的新服务器证书。这个 CA 最终必须作为根证书安装在客户端计算机上。

This is a good post 显示使用 makecert 和 pvk2pfx 的过程。

编辑: It looks like there might be a way 配置 HttpClient 忽略 SSL 错误。但是,我强烈建议您从一开始就尽量不要出现 SSL 错误。

【讨论】:

那么您可以在客户端代码中做些什么来告诉它允许它吗?如果没有将证书作为根证书安装在客户端计算机上,所有浏览器如何实现这一点? @TTT 所有客户端都安装了某些根证书。例如 Verisign 根证书。如果证书由 Verisign 根证书签名(或在链中),则浏览器客户端信任该证书。这是 SSL 工作原理的核心。 我明白这一点。但是我尝试过的所有 3 个浏览器都可以使用 SSL 连接到同一个 url,但我的客户端不能。我想做浏览器正在做的事情。如果未签名的证书在我的机器上不受信任,那么它也不受浏览器信任,但浏览器仍然可以继续。 不用担心。感谢您的链接。 Rick 的解决方案可能会奏效,但在 4.0 中已过时。 @Oppositional 的帖子有 Rick 代码的更新版本。

以上是关于.NET 客户端连接到 ssl Web API的主要内容,如果未能解决你的问题,请参考以下文章

在 .NET 5 Web API 中动态连接到多个数据库(取决于经过身份验证的用户)

web-socket 客户端不会连接到 API

从 Java bean 到 Web 服务的 SSL 连接问题

在 asp.net 中,客户端连接到生产服务器时 Web 服务端点不正确

从 reactjs 客户端连接到安全 Web 套接字 python 服务器

SignalR JavaScript客户端API调用连接