¿Cómo puede agregar un certificado a WebClient (C#)?


Sé que es bastante simple agregar un certificado a un HttpWebRequest. Sin embargo, no he encontrado una manera de hacer el equivalente usando WebClient. Básicamente, quiero enviar una PUBLICACIÓN con un certificado específico usando WebClient.

Cómo lograrías este código exacto usando WebClient:

    var request = (HttpWebRequest) WebRequest.Create("my-url");
    request.Method = "POST";
    request.ClientCertificates.Add(new X509Certificate()); //add cert
Author: Andrew, 2010-01-14

4 answers

Debe subclase y sobreescribir una o más funciones.

class MyWebClient : WebClient
{
    protected override WebRequest GetWebRequest(Uri address)
    {
        HttpWebRequest request = (HttpWebRequest)base.GetWebRequest(address);
        request.ClientCertificates.Add(new X509Certificate());
        return request;
    }
}
 81
Author: Mikael Svenson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-01-14 18:59:26
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;
    }
}

Ahora usted puede con auto firmado cert ! ("La conexión subyacente se cerró: No se pudo establecer una relación de confianza para el canal seguro SSL/TLS.; La conexión subyacente se cerró: No se pudo establecer una relación de confianza para el canal seguro 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));
 9
Author: yop038,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-06-10 21:30:23

Solo subclase WebClient, agregue su propia propiedad ClientCertificates y anule el método WebClient.GetWebRequest(System.Uri). No tengo tiempo para convertir esto a C# de VB, pero debería explicarse por sí mismo:

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
 4
Author: Chris Haas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-01-14 18:53:34

Algo interesante sucedió cuando se instaló un nuevo certificado en nuestros front-ends. Empezamos a recibir el error:

"La conexión subyacente se cerró: No se pudo establecer una relación de confianza para el canal seguro SSL/TLS.; La conexión subyacente se cerró: No se pudo establecer una relación de confianza para el canal seguro SSL/TLS.;"

Nos encargamos del error yendo a cada front-end y abriendo el navegador. Parece que IE estaba almacenando en caché el certificado antiguo. Por al abrir los navegadores, el nuevo certificado entró en vigor. Problema Resuelto!

 4
Author: Jose,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-09-27 19:48:27