2010-01-14 210 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

相关问题