C# .NET客户端连接到ssl Web API

C# .NET客户端连接到ssl Web API,c#,asp.net-web-api,C#,Asp.net Web Api,我有一个ASP.NET Web API,我想与ssl一起使用。目前服务器使用的是自签名证书,目前允许使用http和https。我有一个非常基本的测试客户端,它可以很好地用于http,但不能用于https。我想知道如何修改下面的客户端代码,使其能够与https一起工作。目前IE、Firefox和Chrome都可以使用http和https(带有证书警告)连接到Web API,因此我相信我不必修改服务器上的任何内容,只需修改客户端代码即可。以下是客户端代码: static void Main(stri

我有一个ASP.NET Web API,我想与ssl一起使用。目前服务器使用的是自签名证书,目前允许使用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;
        }
    }
}

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

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

您不需要对IIS中的客户端证书设置执行任何操作(因为我假定您没有使用客户端证书)

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

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

这显示了使用makecert和pvk2pfx的过程

编辑:
HttpClient
配置为忽略SSL错误。但是,我强烈建议您从一开始就尽量不要出现SSL错误。

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

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

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

ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };

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

您的配置中是否已将安全模式设置为Transport?这里可以找到另一个示例:那么在客户端代码中,您是否无法告诉它允许此选项?如果没有将证书作为根证书安装在客户端计算机上,所有浏览器如何完成此任务?@TTT所有客户端都安装了某些根证书。例如,Verisign根证书。如果证书由Verisign根证书签名(或在链中),则浏览器客户端信任该证书。这是SSL工作原理的核心。我理解这一点。但是我尝试过的3种浏览器都可以通过SSL连接到同一个url,但我的客户端不能。我想做浏览器正在做的事情。如果未签名的证书在我的机器上不受信任,那么浏览器也不受信任,但浏览器仍然可以继续。不用担心。谢谢你的链接。Rick的解决方案可能会起作用,但在4.0中已经过时@Oppositional的帖子有Rick代码的更新版本。我同意在prod中使用签名证书,尽管在这种情况下,我们的prod Web API不会公开,因为它只通过我们控制下的自动客户端连接,但它仍然通过internet,这就是为什么我们首先需要SSL。我有两点,1。此解决方案要求开发人员和产品环境之间存在代码差异。我的意思是Prod不需要这个代码,它忽略了证书错误。2.这是特定于应用程序/语言的修复程序。如果jqueryajax请求需要访问这个API呢。在我看来,正如@Devin所提到的,通过升级到根证书,开发机器上应该信任自签名证书。请参阅此链接,该链接使用IIS Express和SSL无警告地设置开发环境,非常适合在开发中测试API。非常感谢。
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };