2010-01-14 3 views
61

Я знаю, что добавить сертификат в HttpWebRequest довольно просто. Тем не менее, я не нашел способ сделать эквивалент с помощью WebClient. В основном, я хочу отправить POST с определенным сертификатом с помощью WebClient.Как добавить сертификат в WebClient (C#)?

Как бы вы выполнить этот точный код с помощью WebClient:

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

ответ

72

Вы должны создать подкласс и переопределить один или несколько функций.

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

Спасибо, это отлично поработало. – Andrew

+0

Удивительный! Попытался выяснить, как это сделать слишком долго. – RandomInsano

4

Просто подкласс WebClient, добавить свои собственные ClientCertificates свойства и переопределить метод WebClient.GetWebRequest(System.Uri). У меня нет времени, чтобы преобразовать это в C# из VB, но это должно быть само за себя:

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

Интересное происходило, когда на наших передних концах был установлен новый сертификат. Мы начали получать сообщение об ошибке:

«Основное соединение было закрыто: не удалось установить доверительные отношения для защищенного канала SSL/TLS. Подключенное соединение было закрыто: не удалось установить доверительные отношения для безопасного канала SSL/TLS. ;»

Мы позаботились об ошибке, перейдя к каждому интерфейсу и открыв браузер. Кажется, что IE кэшировал старый сертификат. Открыв браузер, новый сертификат вступил в силу. Задача решена!

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

Теперь вы можете с самоподписанным сертификатом! («Базовое соединение закрыто: не удалось установить доверительные отношения для 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)); 
+2

Если вы добавите сертификат в webRequest.ClientCertificates, вам больше не нужно переопределять ServerCertificateValidationCallback, который является глобальным параметром, и, таким образом, вы затрагиваете все –

+0

, если вы есть это сообщение об исключении «Подключенное соединение было закрыто: не удалось установить доверительные отношения для безопасного канала SSL/TLS» добавить этот «ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12 | SecurityProtocolType.Ssl3; ' – Fourat

 Смежные вопросы

  • Нет связанных вопросов^_^