Używam poniższy kod i uzyskać HttpRequestException
wyjątek:żądanie HTTPS nie używając HttpClient
using (var handler = new HttpClientHandler())
{
handler.ClientCertificateOptions = ClientCertificateOption.Manual;
handler.SslProtocols = SslProtocols.Tls12;
handler.ClientCertificates.Add(new X509Certificate2(@"C:\certificates\cert.pfx"));
// I also tried to add another certificates that was provided to https access
// by administrators of the site, but it still doesn't work.
//handler.ClientCertificates.Add(new X509Certificate2(@"C:\certificates\cert.crt"));
//handler.ClientCertificates.Add(new X509Certificate2(@"C:\certificates\cert_ca.crt"));
using (var client = new HttpClient(handler))
{
var response = client.GetAsync("https://someurl.com/api.php?arg1=some&arg2=test").GetAwaiter().GetResult();
//^HttpRequestException: An error occurred while sending the request.
}
}
Wyjątek:
WinHttpException: A security error occurred
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
System.Runtime.CompilerServices.ConfiguredTaskAwaitable+ConfiguredTaskAwaiter.GetResult()
System.Net.Http.WinHttpHandler+<StartRequest>d__105.MoveNext()
HttpRequestException: An error occurred while sending the request.
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
System.Runtime.CompilerServices.ConfiguredTaskAwaitable+ConfiguredTaskAwaiter.GetResult()
System.Net.Http.HttpClient+<FinishSendAsync>d__58.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
System.Runtime.CompilerServices.TaskAwaiter.GetResult()
MyApp.Web.Controllers.HomeController.Test() in HomeController.cs
var response = client.GetAsync("https://someurl.com/api.php?arg1=some&arg2=test").GetAwaiter().GetResult();
lambda_method(Closure , object , Object[])
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker+<InvokeActionMethodAsync>d__27.MoveNext()
Próbowałem też na eksport tych samych certyfikatów Windows Store i stosowania certyfikatów to przez Google Chrome i działa dobrze (przeglądarka poprosiła mnie o potwierdzenie zainstalowanego certyfikatu, a następnie załadował zasób).
Dlaczego to nie działa w moim kodzie?
AKTUALIZACJA
Próbowałem też dodać oddzwanianie do sprawdzania poprawności certyfikatu:
handler.ServerCertificateCustomValidationCallback = (message, certificate2, arg3, arg4) =>
{
// I set a breakpoint to this point but it is not catched.
return true;
};
UPDATED2
Świadectwo służy SHA-1. Neil Moss jest wymieniony w komentarzach: support for SHA1 certs is being withdrawn. Jeśli to jest prawdziwy powód, dla którego to nie działa, czy istnieje obejście tego problemu?
ROZWIĄZANIE
Dziękuję Neil Moss do rozwiązania. Zaproponował użycie flagi Tls dla protokołu SSL.
handler.SslProtocols = SslProtocols.Tls12 | SslProtocols.Tls11 | SslProtocols.Tls;
Ale to również wymagane są następujące:
handler.ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => true;
Po dodałem ten jeden działa dobrze.
Proszę podać pełne informacje o błędzie: typ, komunikat i ślad stosu. Jeśli istnieje wyjątek wewnętrzny, co to jest? – Richard
Witam @Richard, zaktualizowałem moje pytanie z komunikatami wyjątku i trakcjami stosu. – hcp
Żeby było jasne, czy próbujesz połączyć się przez HTTPS za pomocą _klienta certyfikatu_, czy próbujesz dołączyć samopodpisany certyfikat _serwera_, który chcesz traktować jako prawidłowy? –