【发布时间】:2020-05-10 20:18:07
【问题描述】:
我有一个控制台应用程序,它在netcore 2.2 的 docker 容器中打包了一个托管服务:
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"]
我一直在使用RestSharp 106.6,没有任何问题。然后今天我决定迁移到net core 3.1,所以除了成功更改所有项目中的程序集版本并成功运行控制台应用程序之外,我还修改了我的 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"]
然后我在使用restsharp客户端时开始出现以下错误:
The SSL connection could not be established, see inner exception. Authentication failed
但内在的例外是一样的。我的猜测是 docker 映像中缺少某些东西,这会阻止客户端工作,因为它可以在本地工作 - 我不认为缺少某些配置,否则本地版本也无法工作。
你们以前遇到过这个问题吗?
谢谢
更新
我正在注销使用 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)
这只是我使用 .NET Core 3.1 再次推进该项目。如果它保留在 .NET Core 2.2 中,它就可以工作。 执行 HTTP 调用的代码:
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;
}
【问题讨论】:
-
该错误与 .NET Core 3 无关,它抱怨 SSL 和身份验证。该问题不包含任何代码,因此无法说出问题所在或代码的作用。您是否尝试将 SSL 与无效或自签名证书一起使用?甚至缺少异常文本。发布完整文本,而不仅仅是消息。该消息清楚地表明细节在内部异常中。您可以通过
Exception.ToString()轻松获取全文 -
确定代码,我会添加它,但问题仍然有效。 .net 核心版本的升级怎么会影响呢?这才是真正的问题。没有代码改动,只是升级项目文件中的版本+dockerfile中的改动
-
或者证书无效?也许它过期了?或者您是否使用代码禁用不再有效的证书验证?你要求人们猜测你的代码做了什么,你如何使用 SSL。这与 Docker 无关,因此此处发布的信息根本没有帮助。 only 相关的事情是异常文本中的单行
-
刚刚粘贴了异常和执行请求的代码。相同的代码,只是版本更改。一个有效,另一个失败。两者都在我的本地机器上工作,但是当我将它们打包在一个容器中时,我得到了 3.1 版本
-
只是为了清楚。我的目标是同一个端点(HTTPS)。我正在使用相同的托管服务提供商。我正在使用相同的代码。当我使用 v.2.2 时,它可以工作。当我使用 v3.1 时它失败了。如果我在我的机器上同时运行 2.2 和 3.1,它就可以工作。我认为这要么是 RestSharp 和 NC3.1 之间的不兼容,要么是 .net core 3.1 的映像本身在 OS TLS 配置方面有所不同
标签: docker openssl tls1.2 restsharp .net-core-3.1