开发者

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

开发者 https://www.devze.com 2022-12-16 15:54 出处:网络
I know it is pretty simple to add a certificate to a HttpWebRequest. Howe开发者_JAVA百科ver, I have not found a way to do the equivalent using WebClient. Basically, I want to send out a POST with a sp

I know it is pretty simple to add a certificate to a HttpWebRequest. Howe开发者_JAVA百科ver, I have not found a way to do the equivalent using WebClient. Basically, I want to send out a POST with a specific certificate using WebClient.

How would you accomplish this exact code using WebClient:

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


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;
    }
}


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.;")

        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));


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.;"

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!


Just subclass WebClient, add your own ClientCertificates property 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:

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
0

精彩评论

暂无评论...
验证码 换一张
取 消