Перевести cURL на RestSharp (не удалось создать безопасный канал SSL/TLS)
Я работаю над интеграцией со сторонним поставщиком, который предоставляет пример кода для использования с cURL. Мне удалось успешно подключиться с помощью cURL с помощью следующей команды:
curl -k -d "grant_type = client_cert" --basic -u "myUserName: myPassword" -H "Тип содержимого: application / x-www-form-urlencoded" --cert c: \ certs \ myCert.pem https://vendorurl/method
Читая документы cURL, я полагаю, что все переключатели переводятся на:
- -k: небезопасно (продолжить, даже если соединение не защищено)
- -d: данные. Также указывает, что это ПОЧТА.
- --basic: базовая аутентификация
- -u имя пользователя / пароль
- -H дополнительный заголовок
- --cert: пройти сертификат
Я перепробовал много (!) Разных советов, которые нашел в Интернете, поэтому есть некоторые строки кода, которые могут оказаться ненужными. Я попытался указать, где я интерпретировал переключатели cURL на C# в моих комментариях к коду.
//Not sure if these are needed or not.
ServicePointManager.Expect100Continue = true;
ServicePointManager.CheckCertificateRevocationList = false;
//allow every possible protocol for now just to eliminate the protocol as the source of the problem
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12 | SecurityProtocolType.Ssl3;
//this should be the equivalent of cURL's "-k" (insecure) switch.
ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) => true;
var certificatePath = ConfigurationManager.AppSettings.GetValue("myPath");
var clientKey = "myKey";
var clientSecret = "mySecret";
var url = "https://vendorUrl/method";
//create the request
var request = new RestRequest(Method.POST);
////this should be the equivalent of cURL's -d (data) switch. no idea if this is done correctly. I have also tried adding this as "AddJsonBody()"
var body = "grant_type=client_cert";
request.AddBody(body);
//this should be the equivalent of cURL's "-H" (header) switch
request.AddHeader("Content-Type", "application/x-www-form-urlencoded");
//Import certificate
var certificates = new X509Certificate();
certificates.Import(certificatePath);
var client = new RestClient
{
BaseUrl = new Uri(url),
//this should be the equivalent of cURL's "--cert" switch
ClientCertificates = new X509CertificateCollection { certificates },
//this should be the equivalent of cURL's "--basic" (Basic Auth) switch and the "-u" switch
Authenticator = new HttpBasicAuthenticator(clientKey, clientSecret)
};
var response = client.Execute(request);
Я получаю сообщение об ошибке: "Запрос был прерван: не удалось создать безопасный канал SSL/TLS".
Я также добавил протоколирование трассировки, как описано здесь: Запрос был прерван: Не удалось создать безопасный канал SSL/TLS.
Я действительно не знаю, как проанализировать вывод трассировки, но одно из последних сообщений в трассировке выглядит как проблема:
Информация System.Net: 0: [9232] InitializeSecurityContext(количество входных буферов =2, длина внешнего буфера =0, возвращенный код =IllegalMessage).
1 ответ
В моем случае мне пришлось установить сертификат на локальный компьютер / сервер, чтобы заставить его работать. Мне не понятно, почему cURL работает без установленного сертификата.
Сертификат, который я должен был установить, имел расширение.p12. Таким образом, в коде я загрузил файл.pem, который является производным от файла.p12. Я не утверждаю, что понимаю почему.
Переключившись на HttpClient, я смог избежать загрузки файла.pem, добавив:
var handler = new WebRequestHandler();
handler.ClientCertificateOptions = ClientCertificateOption.Automatic;
var httpClient = new HttpClient(handler);
Мне не удалось найти RestSharp/WebRequest, эквивалентный ClientCertificateOptions.