78 votes

Comment ajouter un certificat au WebClient (C#) ?

Je sais qu'il est assez simple d'ajouter un certificat à une HttpWebRequest. Cependant, je n'ai pas trouvé de moyen de faire l'équivalent avec WebClient. En gros, je veux envoyer un POST avec un certificat spécifique en utilisant WebClient.

Comment réaliser ce code exact en utilisant WebClient :

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

101voto

Mikael Svenson Points 18243

Vous devez sous-classer et surcharger une ou plusieurs fonctions.

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

12voto

yop038 Points 21
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;
    }
}

Maintenant vous pouvez le faire avec un certificat auto-signé ! ("La connexion sous-jacente a été fermée : Impossible d'établir une relation de confiance pour le canal sécurisé SSL/TLS ; La connexion sous-jacente a été fermée : Impossible d'établir une relation de confiance pour le canal sécurisé 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));

5voto

Jose Points 21

Une chose intéressante s'est produite lorsqu'un nouveau certificat a été installé sur nos front-ends. Nous avons commencé à recevoir l'erreur :

"La connexion sous-jacente a été fermée : Impossible d'établir une relation de confiance pour le canal sécurisé SSL/TLS. ; La connexion sous-jacente a été fermée : Impossible d'établir une relation de confiance pour le canal sécurisé SSL/TLS. ;"

Nous avons pris soin de l'erreur en allant sur chaque front-end et en ouvrant le navigateur. Il semble qu'IE mettait en cache l'ancien certificat. En ouvrant les navigateurs, le nouveau certificat a pris effet. Problème résolu !

4voto

Chris Haas Points 23212

Il suffit de sous-classer WebClient ajouter votre propre ClientCertificates et remplacer la propriété WebClient.GetWebRequest(System.Uri) méthode. Je n'ai pas le temps de convertir cette méthode en C# à partir de VB, mais elle devrait être assez explicite :

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X