I am trying to make https call using HttpClient in the azure function app(C#) running in Linux OS.
The cert(.cer) is a CA signed intermediate cert(with chain to root cert) uploaded in the Public Certificates of Function App to be used in the function app.
Here is the Function App Code I am using to create HttpClient:
static HttpClient GetHttpClient()
{
string certificatePath = "var/ssl/certs/certificatethumprint.der";
if (certificatePath == null) {
throw new Exception("Environment Variable is null");
}
HttpClient httpClient = null;
var bytes = File.ReadAllBytes(certificatePath);
X509Certificate2 cert = new(bytes);
handler = new HttpClientHandler();
handler.ClientCertificates.Add(cert);
if (handler != null)
{
httpClient = new HttpClient(handler);
}
return httpClient;
}
Here is the code using httpClient:
static HttpClient httpClient = GetHttpClient();
HttpRequestMessage httpWebRequest = GetHttpRequest(messageBody, log);
HttpResponseMessage response = null;
try {
response = await httpClient.SendAsync(httpWebRequest);
}
Get HttpRequest returns the HttpRequest with request parameters.
While I use the code above I am getting this exception:
Exception occurred during http call: The SSL connection could not be established, see inner exception. stackTrace: at System.Net.Http.ConnectHelper.EstablishSslConnectionAsync(SslClientAuthenticationOptions sslOptions, HttpRequestMessage request, Boolean async, Stream stream, CancellationToken cancellationToken) at System.Net.Http.HttpConnectionPool.ConnectAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken) at System.Net.Http.HttpConnectionPool.CreateHttp11ConnectionAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken) at System.Net.Http.HttpConnectionPool.AddHttp11ConnectionAsync(HttpRequestMessage request) at System.Threading.Tasks.TaskCompletionSourceWithCancellation`1.WaitWithCancellationAsync(CancellationToken cancellationToken) at System.Net.Http.HttpConnectionPool.GetHttp11ConnectionAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken) at System.Net.Http.HttpConnectionPool.SendWithVersio nDetectionAndRetryAsync(HttpRequestMessage request, Boolean async, Boolean doRequestAuth, CancellationToken cancellationToken) at System.Net.Http.DiagnosticsHandler.SendAsyncCore(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken) at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken) at System.Net.Http.HttpClient.g__Core|83_0(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationTokenSource cts, Boolean disposeCts, CancellationTokenSource pendingRequestsCts, CancellationToken originalCancellationToken) at Function.FunctionApp.FunctionApp.Method(Parameter parameter) in /opt/vsts-agent-linux-x64-2.173.0.tar.gz/_work/1/s/Function/Function.FunctionApp/FunctionApp.cs:line 116 type: System.Net.Http.HttpRequestException InnerException: System.Security.Authentication.AuthenticationException: The r emote certificate is invalid because of errors in the certificate chain: PartialChain at System.Net.Security.SslStream.SendAuthResetSignal(ProtocolToken message, ExceptionDispatchInfo exception) at System.Net.Security.SslStream.CompleteHandshake(SslAuthenticationOptions sslAuthenticationOptions) at System.Net.Security.SslStream.ForceAuthenticationAsync[TIOAdapter](TIOAdapter adapter, Boolean receiveFirst, Byte[] reAuthenticationData, Boolean isApm) at System.Net.Http.ConnectHelper.EstablishSslConnectionAsync(SslClientAuthenticationOptions sslOptions, HttpRequestMessage request, Boolean async, Stream stream, CancellationToken cancellationToken)
The message in exception:
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: PartialChain
I do not want to force validate the cert using the code below as I'll need to deploy this in production and it is not the best practice for production environment:
handler = new HttpClientHandler
{
ClientCertificateOptions = ClientCertificateOption.Manual,
ServerCertificateCustomValidationCallback =
(httpRequestMessage, cert, cetChain, policyErrors) =>
{
return true; //Not a best practice/ not safe
},
SslProtocols = SslProtocols.Tls12
};
Any suggestion/help would be much appreciated.
Based on the suggestion, when I didn't use any cert to make https call from client I get this exception:
Error when sending the http request: The SSL connection could not be established, see inner exception. Information 2022-11-23 19:11:56.999 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: PartialChain at System.Net.Security.SslStream.SendAuthResetSignal(ProtocolToken message, ExceptionDispatchInfo exception) at System.Net.Security.SslStream.CompleteHandshake(SslAuthenticationOptions sslAuthenticationOptions) at System.Net.Security.SslStream.ForceAuthenticationAsync[TIOAdapter](TIOAdapter adapter, Boolean receiveFirst, Byte[] reAuthenticationData, Boolean isApm) at System.Net.Http.ConnectHelper.EstablishSslConnectionAsync(SslClientAuthenticationOptions sslOptions, HttpRequestMessage request, Boolean async, Stream stream, CancellationToken cancellationToken) --- End of inner exception stack trace --- at System.Net.Http.ConnectHelper.EstablishSslConnectionAsync(SslClientAuthenticationOptions sslOptions, HttpRequestMessage request, Boolean async, Stream stream, CancellationToken cancellationToken) at System.Net.Http.HttpConnectionPool.ConnectAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken) at System.Net.Http.HttpConnectionPool.CreateHttp11ConnectionAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken) at System.Net.Http.HttpConnectionPool.AddHttp11ConnectionAsync(HttpRequestMessage request) at System.Threading.Tasks.TaskCompletionSourceWithCancellation`1.WaitWithCancellationAsync(CancellationToken cancellationToken) at System.Net.Http.HttpConnectionPool.GetHttp11ConnectionAsync(HttpRequestMessa
When you are connecting to a secure server, only the server needs a certificate. I don't fully understand what you are doing with HttpClient and servers, but at least in the GetHttpClient(), I don't think there is a need to set the certificate yourself. Hope this helps!
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.