I have a console APP which is has a hosted service packed up in a docker container in netcore 2.2
:
FROM microsoft/dotnet:2.2-sdk AS builder
WORKDIR /service
# copy csproj and restore as distinct layers
COPY . .
RUN dotnet restore ./Project.sln
# copy everything else and build
COPY . .
RUN dotnet publish ./Project/Project.csproj -c Release -o /service/out
# build runtime image
FROM microsoft/dotnet:2.2.0-aspnetcore-runtime
WORKDIR /service
COPY --from=builder /service/out ./
ENV ASPNETCORE_ENVIRONMENT Production
ENTRYPOINT ["dotnet", "Project.dll"]
I have been using RestSharp 106.6
with no issues. Then today I decided to migrate to net core 3.1
so apart from changing the assembly version in all projects with success and running the console app successfully as well, I modified my Dockerfile:
FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS builder
WORKDIR /service
# copy csproj and restore as distinct layers
COPY . .
RUN dotnet restore ./Project.sln
# copy everything else and build
COPY . .
RUN dotnet publish ./Project/Project.csproj -c Release -o /service/out
# build runtime image
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1 AS runtime
WORKDIR /service
COPY --from=builder /service/out ./
ENV ASPNETCORE_ENVIRONMENT Production
ENTRYPOINT ["dotnet", "Project.dll"]
Then I started getting the following error when using the restsharp client:
The SSL connection could not be established, see inner exception. Authentication failed
But the inner exception is saying the same. My guess is that there is something missing in the docker image that is preventing the client to work because it works locally - I don't think there is some configuration missing otherwise the local version would not work either.
Have you guys come across this problem before?
Thanks
UPDATE
I'm logging out the actual exception message that I get when using RestSharp:
---> System.Net.Http.HttpRequestException: The SSL connection could not be established, see inner exception.
---> System.Security.Authentication.AuthenticationException: Authentication failed, see inner exception.
---> Interop+OpenSsl+SslException: SSL Handshake failed with OpenSSL error - SSL_ERROR_SSL.
---> Interop+Crypto+OpenSslCryptographicException: error:1425F102:SSL routines:ssl_choose_client_version:unsupported protocol
--- End of inner exception stack trace ---
at Interop.OpenSsl.DoSslHandshake(SafeSslHandle context, Byte[] recvBuf, Int32 recvOffset, Int32 recvCount, Byte[]& sendBuf, Int32& sendCount)
at System.Net.Security.SslStreamPal.HandshakeInternal(SafeFreeCredentials credential, SafeDeleteContext& context, ArraySegment`1 inputBuffer, Byte[]& outputBuffer, SslAuthenticationOptions sslAuthenticationOptions)
--- End of inner exception stack trace ---
at System.Net.Security.SslStream.StartSendAuthResetSignal(ProtocolToken message, AsyncProtocolRequest asyncRequest, ExceptionDispatchInfo exception)
at System.Net.Security.SslStream.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslStream.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslStream.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslStream.ReadFrameCallback(AsyncProtocolRequest asyncRequest)
--- End of stack trace from previous location where exception was thrown ---
at System.Net.Security.SslStream.ThrowIfExceptional()
at System.Net.Security.SslStream.InternalEndProcessAuthentication(LazyAsyncResult lazyResult)
at System.Net.Security.SslStream.EndProcessAuthentication(IAsyncResult result)
at System.Net.Security.SslStream.EndAuthenticateAsClient(IAsyncResult asyncResult)
at System.Net.Security.SslStream.<>c.<AuthenticateAsClientAsync>b__65_1(IAsyncResult iar)
at System.Threading.Tasks.TaskFactory`1.FromAsyncCoreLogic(IAsyncResult iar, Func`2 endFunction, Action`1 endAction, Task`1 promise, Boolean requiresSynchronization)
--- End of stack trace from previous location where exception was thrown ---
at System.Net.Http.ConnectHelper.EstablishSslConnectionAsyncCore(Stream stream, SslClientAuthenticationOptions sslOptions, CancellationToken cancellationToken)
--- End of inner exception stack trace ---
at System.Net.Http.ConnectHelper.EstablishSslConnectionAsyncCore(Stream stream, SslClientAuthenticationOptions sslOptions, CancellationToken cancellationToken)
at System.Net.Http.HttpConnectionPool.ConnectAsync(HttpRequestMessage request, Boolean allowHttp2, CancellationToken cancellationToken)
at System.Net.Http.HttpConnectionPool.CreateHttp11ConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at System.Net.Http.HttpConnectionPool.GetHttpConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken)
at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at System.Net.Http.DecompressionHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at System.Net.Http.HttpClient.FinishSendAsyncUnbuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts)
at System.Net.HttpWebRequest.SendRequest()
at System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
--- End of inner exception stack trace ---
at System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
at RestSharp.Http.GetRawResponseAsync(IAsyncResult result, Action`1 callback)
at RestSharp.Http.ResponseCallback(IAsyncResult result, Action`1 callback)
That's just me rolling forward again the project using .NET Core 3.1. If that stays in .NET Core 2.2 it just works. The code to perform the HTTP Call:
public async Task<MyResponse> GetAsync()
{
MyResponse myResponse = null;
var stopWatch = new Stopwatch();
stopWatch.Start();
try
{
var request = new RestRequest(Method.GET);
request.AddHeader("Accept", "application/json");
var restResponse = await _restClient.ExecuteGetAsync(request);
if(restResponse.IsSuccessful)
{
gobResponse = JsonConvert.DeserializeObject<MyResponse>(restResponse.Content, DateTimeConverter);
Logger.Info($"Retrieved my response. Took: {stopWatch.ElapsedMilliseconds}ms. StatusCode={restResponse.StatusCode.ToString()}");
}
else
{
Logger.Error(restResponse.ErrorException.ToString(), "Error performing request");
}
}
catch(Exception ex)
{
Logger.Error(ex.ToString(), $"Error executing HTTP client");
}
return myResponse;
}