.NET 和 MySQL 错误 - 对 SSPI 的调用失败...“收到的消息意外或格式错误”和“提供给函数的缓冲区太小”

Posted

技术标签:

【中文标题】.NET 和 MySQL 错误 - 对 SSPI 的调用失败...“收到的消息意外或格式错误”和“提供给函数的缓冲区太小”【英文标题】:.NET & MySQL error - A call to SSPI failed ... "message received was unexpected or badly formatted" AND "buffers supplied to a function was too small" 【发布时间】:2018-03-13 02:44:39 【问题描述】:

我希望这不是一个太含糊的问题,但我已经看得很远了,但没有找到任何东西对这个错误有帮助。

我有一个 .NET 4.5.2 Web 服务层(使用 ServiceStack 和 Dapper),自从我们部署服务后,它就很少收到这两个错误。

第一个错误:

2017-09-29 18:13:26.637 +00:00 [Error] Class: "TokenRepository" | Method: "GetToken"
System.Security.Authentication.AuthenticationException: A call to SSPI failed, see inner exception. ---> System.ComponentModel.Win32Exception: The message received was unexpected or badly formatted
   --- End of inner exception stack trace ---
   at System.Net.Security.SslState.StartSendAuthResetSignal(ProtocolToken message, AsyncProtocolRequest asyncRequest, Exception exception)
   at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.ForceAuthentication(Boolean receiveFirst, Byte[] buffer, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.ProcessAuthentication(LazyAsyncResult lazyResult)
   at mysql.Data.MySqlClient.NativeDriver.StartSSL()
   at MySql.Data.MySqlClient.NativeDriver.Open()
   at MySql.Data.MySqlClient.Driver.Open()
   at MySql.Data.MySqlClient.Driver.Create(MySqlConnectionStringBuilder settings)
   at MySql.Data.MySqlClient.MySqlPool.CreateNewPooledConnection()
   at MySql.Data.MySqlClient.MySqlPool.GetPooledConnection()
   at MySql.Data.MySqlClient.MySqlPool.TryToGetDriver()
   at MySql.Data.MySqlClient.MySqlPool.GetConnection()
   at MySql.Data.MySqlClient.MySqlConnection.Open()
   at Dapper.SqlMapper.<QueryImpl>d__125`1.MoveNext()
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
   at Dapper.SqlMapper.Query[T](IDbConnection cnn, String sql, Object param, IDbTransaction transaction, Boolean buffered, Nullable`1 commandTimeout, Nullable`1 commandType)
   at myApp.Services.Data.Impl.TokenRepository.GetToken(String token) in E:\Jenkins\workspace\myApp\src\Services.Data\Impl\TokenRepository.cs:line 191

第二个……

2017-09-19 15:40:51.040 +00:00 [Error] Class: "myApp.Services.Data.Impl.SystemRepository" | Method: "GetAttributes"
System.Security.Authentication.AuthenticationException: A call to SSPI failed, see inner exception. ---> System.ComponentModel.Win32Exception: The buffers supplied to a function was too small
   --- End of inner exception stack trace ---
   at System.Net.Security.SslState.StartSendAuthResetSignal(ProtocolToken message, AsyncProtocolRequest asyncRequest, Exception exception)
   at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.ForceAuthentication(Boolean receiveFirst, Byte[] buffer, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.ProcessAuthentication(LazyAsyncResult lazyResult)
   at MySql.Data.MySqlClient.NativeDriver.StartSSL()
   at MySql.Data.MySqlClient.NativeDriver.Open()
   at MySql.Data.MySqlClient.Driver.Open()
   at MySql.Data.MySqlClient.Driver.Create(MySqlConnectionStringBuilder settings)
   at MySql.Data.MySqlClient.MySqlPool.CreateNewPooledConnection()
   at MySql.Data.MySqlClient.MySqlPool.GetPooledConnection()
   at MySql.Data.MySqlClient.MySqlPool.TryToGetDriver()
   at MySql.Data.MySqlClient.MySqlPool.GetConnection()
   at MySql.Data.MySqlClient.MySqlConnection.Open()
   at Dapper.SqlMapper.<QueryImpl>d__125`1.MoveNext()
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
   at Dapper.SqlMapper.Query[T](IDbConnection cnn, String sql, Object param, IDbTransaction transaction, Boolean buffered, Nullable`1 commandTimeout, Nullable`1 commandType)
   at myApp.Services.Data.Impl.SystemRepository.GetAttributes() in E:\Jenkins\workspace\myApp\src\Services.Data\Impl\SystemRepository.cs:line 38

我的堆栈上的一点背景:

.NET 4.5.2 小巧玲珑 1.50.2.0 ServiceStack 4.5.4 MySQL 5.6(使用Amazon Aurora)

在我们的任何其他环境中都没有收到此错误,我们运行 Aurora,只是在 Amazon RDS 上运行 MySQL 5.7.17。

正如我所提到的,这些错误是偶发的,并不总是发生在相同的方法/服务上,但它们总是在使用 Dapper 从服务层到 MySQL 数据库执行 SQL 命令时发生。

是否有进一步调试这个问题或者是否有任何与 MySql/Aurora/Dapper 相关的已知问题?经过研究,我无法找到任何东西。

【问题讨论】:

这个 Oracle 页面上的错误可能有些问题,但我没有 Oracle 支持标识符来访问它。也许这里有人可以说出他们对此有何看法:support.oracle.com/knowledge/Oracle%20Database%20Products/… 你好。在类似的场景中,我们也遇到了完全相同的问题 - .NET Web API 和 WEB MVC 项目,MYSQL DB Connection 部署在 AWS + Aurora 上。我们不断收到的消息似乎指向同一个问题,它们有 3 种“风格”:尝试读取流的末尾提供用于验证的消息或签名已已更改收到的消息出乎意料或格式错误。您找到任何解决方案了吗?谢谢! @PriscaruAlin 这些是我们仍然看到的相同错误,但不,我还没有找到任何解决方案。我最好的猜测是 MySQL 版本 5.6.x 是问题所在,它已在 5.7 中修复。亚马逊只需在 Aurora 上更新到 5.7。有AWS support thread 的人请求更新。我最终实现了一个“重试”库来检测执行数据库事务时的故障,然后重试它们。它似乎正在使用这项工作。在 C# 中,我使用了Polly 【参考方案1】:

看看这个https://github.com/mysql-net/MySqlConnector/issues/428

我在使用类似的技术堆栈时遇到了同样的错误。一个简单的解决方法是在您的 connectionString 中添加 SslMode=None,它应该可以工作。

【讨论】:

禁用传输层加密并不是一个好的解决方案! 我认为如果您在 AWS 私有云上运行 MySql 或 Aurora RDS 实例,是否启用 SSLMode 并不重要。 RDS 将只允许来自已附加 RDS 安全组的实例的连接,因此在我看来,我建议的解决方案仍然有效。 @Zero3 对于这个问题应该有什么可行的解决方案? @Wackie 建议的解决方案:1)重试发送一次,2)升级 Windows 版本 3)从 .NET Framework 升级到 .NET Core / .NET 5。【参考方案2】:

第二个错误(“提供给函数的缓冲区太小”)是 .NET 框架中的一个已知问题。见https://github.com/dotnet/corefx/issues/1854。

一种可能的解决方法是在看到此故障时重试连接一次。它至少从 GitHub 问题中解决了邮件发送用例中的问题。

对于它的价值,我在运行 Windows Server 2012 R2 的生产系统上看到了这个问题,但在运行 Windows Server 2016 的生产系统上没有看到这个问题。所以我认为潜在问题可能已经在这些版本的 Windows 之间得到修复.

【讨论】:

我在 AWS 提供的 Windows Server 2016 上遇到了问题

以上是关于.NET 和 MySQL 错误 - 对 SSPI 的调用失败...“收到的消息意外或格式错误”和“提供给函数的缓冲区太小”的主要内容,如果未能解决你的问题,请参考以下文章

I/O 错误:SSO 失败:未加载本机 SSPI 库

apns sharp 中的 iPhone 证书错误调用 SSPI 失败

System.Security.Authentication.AuthenticationException:对 SSPI 的调用失败,请参阅内部异常

除非客户端和服务器使用相同的 Windows 身份,否则带有 sspi 的 WCF Net.tcp 会失败

WCF 服务 - 身份验证/SSPI 错误

WCF“对 SSPI 的调用失败,请参阅内部异常”