Как вы можете добавить сертификат в WebClient (C#)?
Я знаю, что довольно просто добавить сертификат в HttpWebRequest. Тем не менее, я не нашел способ сделать эквивалент с помощью WebClient. По сути, я хочу отправить POST с определенным сертификатом, используя WebClient.
Как бы вы выполнили этот точный код, используя WebClient:
var request = (HttpWebRequest) WebRequest.Create("my-url");
request.Method = "POST";
request.ClientCertificates.Add(new X509Certificate()); //add cert
4 ответа
Вы должны создать подкласс и переопределить одну или несколько функций.
class MyWebClient : WebClient
{
protected override WebRequest GetWebRequest(Uri address)
{
HttpWebRequest request = (HttpWebRequest)base.GetWebRequest(address);
request.ClientCertificates.Add(new X509Certificate());
return request;
}
}
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));
Интересная вещь произошла, когда новый сертификат был установлен на наших интерфейсах. Мы начали получать ошибку:
"Базовое соединение было закрыто: не удалось установить доверительные отношения для безопасного канала SSL/TLS. Базовое соединение было закрыто: не удалось установить доверительные отношения для безопасного канала SSL/TLS.;"
Мы позаботились об ошибке, зайдя в каждый интерфейс и открыв браузер. Похоже, IE кешировал старый сертификат. Открыв браузеры, новый сертификат вступил в силу. Задача решена!
Просто подкласс 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