2010-01-14 92 views
61

我知道這是很簡單的一個證書添加到HttpWebRequest的。但是,我還沒有找到使用WebClient進行等效的方法。基本上,我想使用WebClient發送帶有特定證書的POST。如何將證書添加到WebClient(C#)?

你會如何使用Web客戶端完成這個確切的代碼:

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 2010-01-14 19:03:48

+0

太棒了!一直試圖找出如何爲遠遠太長 – RandomInsano 2010-12-03 21:15:31

4

只要繼承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 
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,這是一個全局設置,因此你如果影響一切 – 2016-05-02 14:11:40

+0

有此異常消息'基礎連接已關閉:無法爲SSL信任關係/ TLS安全channel'加入這個'ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12 | SecurityProtocolType.Ssl3;' – Fourat 2017-03-02 10:27:59