Я новичок в службах REST и пытаюсь вызвать службу REST от коллеги, защищенную только именем пользователя и паролем.
С помощью Postman все в порядке, у меня есть GET к URL-адресу, я выбираю «Базовую аутентификацию», задаю имя пользователя и пароль и получаю ожидаемый результат.
Теперь я попробовал это с помощью кода: Вызовы других веб-сервисов для каждого кода без пользователя/пароля работают нормально, но здесь я просто получаю исключение:
public async Task<List<string>> MinimalProblemShowcase()
{
string authenticationString = $"{clientId}:{clientSecret}"; // no typo, values are copy/pasted
string base64EncodedAuthenticationString = Convert.ToBase64String(Encoding.UTF8.GetBytes(authenticationString));
_client.DefaultRequestHeaders.Add("Authorization", "Basic " + base64EncodedAuthenticationString);
try
{
var httpResponse = _client.GetAsync(Url).Result;
// ToDo: evaluate httpResponse - but we don't get here...
}
catch (Exception ex)
{
// ...instead we drop here:
// System.Net.Http.HttpRequestException:
// The SSL connection could not be established, see inner exception.
// --->System.Security.Authentication.AuthenticationException:
// The remote certificate is invalid because of errors in the certificate chain: UntrustedRoot
}
return [];
}
Как указано, я получаю
System.Net.Http.HttpRequestException:
The SSL connection could not be established, see inner exception.
---> System.Security.Authentication.AuthenticationException:
The remote certificate is invalid because of errors in the certificate chain: UntrustedRoot
Я не знаю, как явно использовать сертификаты, но если да, то это на той же машине...
Подозреваю, что мне не хватает лишь незначительной детали, но что...? Спасибо за любую подсказку или помощь!
Предполагая, что _client
является экземпляром HttpClient
, по умолчанию принимаются только действительные/доверенные сертификаты SSL/TLS сервера.
Извините, конечно, _client — это экземпляр HttpClient. И одна из моих попыток заключалась в ожидании _client.GetAsync(Url), которая дала тот же результат.
Вы можете игнорировать проблему недоверия сертификата, настроив httpclient
var httpClientHandler = new HttpClientHandler();
httpClientHandler.ServerCertificateCustomValidationCallback = (message, cert, chain, sslPolicyErrors) =>{return true;};
builder.Services.AddScoped<HttpClient>(sp => new HttpClient(httpClientHandler));
Или вы можете выполнить некоторую проверку с помощью того сертификата, который вы используете.
httpClientHandler.ServerCertificateCustomValidationCallback = (message, cert, chain, sslPolicyErrors) => {
if (cert.GetCertHashString() == "A7E2BA992F4F2BE220559B8A5371F05A00A6E750") //FingerPrint of the certificate
{
return true;
}
return false;
};
Стандартный способ решить эту проблему — проверить, установлены ли в Windows сертификаты цепочек сертификатов. Если они установлены правильно, вышеуказанные настройки вам не потребуются. Оно должно быть действительным, когда вы работаете с Visual Studio.
Извините, добавил ваше предложение, но без изменений.
@Мартин, моя вина. Должно быть AddScoped<HttpClient>
просто убедитесь, что ваш инъекционный клиент использует эту услугу.
Спасибо большое, второй способ решил проблему. Мне потребовалось некоторое время, чтобы понять причину: вызываемый сервер использует самозаверяющий сертификат...
СОВЕТ. Не используйте
Task.Result
здесь_client.GetAsync(Url).Result
. Вместо этого используйтеawait _client.GetAsync(Url)
.