如何将证书添加到 WebClient (C#)?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2066489/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 23:12:03  来源:igfitidea点击:

How can you add a Certificate to WebClient (C#)?

c#httpwebrequestcertificatewebclienthttp-post

提问by Andrew

I know it is pretty simple to add a certificate to a HttpWebRequest. However, I have not found a way to do the equivalent using WebClient. Basicly, I want to send out a POST with a specific certificate using WebClient.

我知道将证书添加到 HttpWebRequest 非常简单。但是,我还没有找到使用 WebClient 进行等效操作的方法。基本上,我想使用 WebClient 发送带有特定证书的 POST。

How would you accomplish this exact code using WebClient:

你将如何使用 WebClient 完成这个确切的代码:

    var request = (HttpWebRequest) WebRequest.Create("my-url");
    request.Method = "POST";
    request.ClientCertificates.Add(new X509Certificate()); //add cert

采纳答案by Mikael Svenson

You must subclass and override one or more functions.

您必须子类化并覆盖一个或多个函数。

class MyWebClient : WebClient
{
    protected override WebRequest GetWebRequest(Uri address)
    {
        HttpWebRequest request = (HttpWebRequest)base.GetWebRequest(address);
        request.ClientCertificates.Add(new X509Certificate());
        return request;
    }
}

回答by Chris Haas

Just subclass WebClient, add your own ClientCertificatesproperty and override the WebClient.GetWebRequest(System.Uri)method. I don't have time to convert this to C# from VB but it should be fairly self-explanatory:

只需 subclass WebClient,添加您自己的ClientCertificates属性并覆盖该WebClient.GetWebRequest(System.Uri)方法。我没有时间将其从 VB 转换为 C#,但它应该是不言自明的:

Imports System.Net

Public Class WebClient2
    Inherits System.Net.WebClient

    Private _ClientCertificates As New System.Security.Cryptography.X509Certificates.X509CertificateCollection
    Public ReadOnly Property ClientCertificates() As System.Security.Cryptography.X509Certificates.X509CertificateCollection
        Get
            Return Me._ClientCertificates
        End Get
    End Property
    Protected Overrides Function GetWebRequest(ByVal address As System.Uri) As System.Net.WebRequest
        Dim R = MyBase.GetWebRequest(address)
        If TypeOf R Is HttpWebRequest Then
            Dim WR = DirectCast(R, HttpWebRequest)
            If Me._ClientCertificates IsNot Nothing AndAlso Me._ClientCertificates.Count > 0 Then
                WR.ClientCertificates.AddRange(Me._ClientCertificates)
            End If
        End If
        Return R
    End Function
End Class

回答by Jose

An interesting thing happened when a new certificate was installed on our front-ends. We started getting the error:

在我们的前端安装新证书时发生了一件有趣的事情。我们开始收到错误:

"The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel.; The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel.;"

“底层连接已关闭:无法为 SSL/TLS 安全通道建立信任关系。;底层连接已关闭:无法为 SSL/TLS 安全通道建立信任关系。”

We took care of the error by going to each front-end and opening the browser. It seems that IE was caching the old certificate. By opening the browsers, the new certificate took effect. Problem Solved!

我们通过转到每个前端并打开浏览器来处理错误。似乎 IE 正在缓存旧证书。通过打开浏览器,新证书生效。问题解决了!

回答by yop038

public class CertificateWebClient : WebClient
{
    private readonly X509Certificate2 certificate;

    public CertificateWebClient(X509Certificate2 cert)
    {
        certificate = cert;
    }

    protected override WebRequest GetWebRequest(Uri address)
    {
        HttpWebRequest request = (HttpWebRequest)base.GetWebRequest(address);

        System.Net.ServicePointManager.ServerCertificateValidationCallback = delegate(Object obj, X509Certificate X509certificate, X509Chain chain, System.Net.Security.SslPolicyErrors errors)
        {
            return true;
        };

        request.ClientCertificates.Add(certificate);
        return request;
    }
}

Now you can with self signed cert ! ("The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel.; The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel.;")

现在您可以使用自签名证书!(“底层连接已关闭:无法为 SSL/TLS 安全通道建立信任关系。;底层连接已关闭:无法为 SSL/TLS 安全通道建立信任关系。”)

        X509Certificate2 Cert = new X509Certificate2("client.p12", "1234", X509KeyStorageFlags.MachineKeySet);

        // Create a new WebClient instance.
        CertificateWebClient myWebClient = new CertificateWebClient(Cert);

        string fileName = Installation.destXML;
        string uriString = "https://xxxxxxx.xx:918";
        // Upload the file to the URI.
        // The 'UploadFile(uriString,fileName)' method implicitly uses HTTP POST method.
        byte[] responseArray = myWebClient.UploadFile(uriString, fileName);

        // Decode and display the response.
        Console.WriteLine("\nResponse Received.The contents of the file uploaded are:\n{0}",
            System.Text.Encoding.ASCII.GetString(responseArray));