Пишу маленький утилит для совершения HTTP-звонков. Сервер использует самозаверяющий сертификат SSL. Проблема в том, что когда я пытаюсь опубликовать что-то на сервере, приложение завершает работу без исключений, консоль возвращает состояние выхода 0. Выполнение HTTP-кода непосредственно из браузера работает, и я получаю ответ обратно.
Я уже посмотрел на stackoverflow и там были идеи добавить типы протоколов безопасности в ServicePointManager.SecurityProtocol. Я перепробовал большинство предложенных решений, но застрял :)
Вот мой код:
private async Task<T> PostAsync<T>(string address, string payload)
{
var endpointAddress = address;
var handler = new HttpClientHandler();
if (!_certificateSigned)
{
handler.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator;
}
using (var httpClient = new HttpClient(handler))
{
ServicePointManager.SecurityProtocol =
SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
try
{
httpClient.DefaultRequestHeaders.Accept.Clear();
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
httpClient.DefaultRequestHeaders.Authorization = AuthenticationHeader;
var json = new StringContent(payload, Encoding.UTF8, "application/json");
var response = await httpClient.PostAsJsonAsync(address, json);
response.EnsureSuccessStatusCode();
if (response.IsSuccessStatusCode)
{
var responseData = await response.Content.ReadAsStringAsync();
return JsonConvert.DeserializeObject<T>(responseData);
}
}
catch (Exception ex)
{
}
}
return default(T);
}
Короче, я пытаюсь переписать этот вызов API curl:
curl -u "${CATTLE_ACCESS_KEY}:${CATTLE_SECRET_KEY}" \
-X POST \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
'https://192.168.5.30:444/v3/clusterregistrationtokens'
Интересно, что метод GetAsyn c работает просто отлично. Код для get asyn c method
private async Task<T> GetAsync<T>(string address)
{
var endpointAddress = address;
var handler = new HttpClientHandler();
using (var httpClient = new HttpClient(handler))
{
if (!_certificateSigned)
{
handler.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator;
}
try
{
httpClient.DefaultRequestHeaders.Authorization = AuthenticationHeader;
var response = await httpClient.GetAsync(endpointAddress);
if (response.IsSuccessStatusCode)
{
var responseData = await response.Content.ReadAsStringAsync();
return JsonConvert.DeserializeObject<T>(responseData);
}
}
catch (Exception ex)
{
}
}
return default(T);
}
И это мое значение заголовка авторизации
private AuthenticationHeaderValue AuthenticationHeader => new AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.UTF8.GetBytes($"{_accessKey}:{_secretKey}")));
Журнал от фиддлера
[Fiddler] Соединение до «192.168.5.30» не удалось. System.Security.SecurityException Не удалось согласовать HTTPS-соединение с server.fiddler.network.https> HTTPS-квитирование 192.168.5.30 (для # 21) не удалось. System.Security.Authentication.AuthenticationException Сбой вызова SSPI, см. Внутреннее исключение. <Запрошенная функция не поддерживается </p>
Win32 (SChannel) Код собственной ошибки: 0x80090302