在使用OWIN身份验证连接Azure SQL时,为什么会出现“GZip头中的魔数不正确”的错误?

5

在Google或SO上没有与此特定问题相关的内容,因此要提出一个新问题。我创建了一个全新的Asp.Net MVC Web应用程序,其中包含标准的用户安全选项。我还在Azure中创建了一个空数据库。

我只更改了默认连接字符串,将其更改为:

  <connectionStrings>
    <add name="DefaultConnection" 
         connectionString="data source=mydatabase.database.windows.net;initial catalog=Feedback;persist security info=True;user id=LeaveFeedbackuser;password=mypassword;MultipleActiveResultSets=True;App=EntityFramework"
         providerName="System.Data.SqlClient" />
  </connectionStrings>

将默认连接工厂更改为以下内容:
  <entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework">
      <parameters>
        <parameter value="v12.0" />
      </parameters>
    </defaultConnectionFactory>
    <providers>
      <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
    </providers>
  </entityFramework>

尝试注册时(正常情况下应创建AspNetUsers和相关表),我收到以下错误消息:

GZip头中的幻数不正确。确保传递了一个GZip流。说明:当前Web请求执行期间发生未处理的异常。请查看堆栈跟踪以获取有关错误的更多信息以及错误在代码中的起源。

异常详细信息:System.IO.InvalidDataException: GZip头中的幻数不正确。确保传递了一个GZip流。

来源错误:

第153行:{第154行:var user = new ApplicationUser {UserName = model.Email,Email = model.Email };第155行:var result = await UserManager.CreateAsync(user,model.Password);第156行:如果(result.Succeeded)第157行:{

这与GZip有什么关系?导致此错误的原因是什么?这已经使我无法将OWIN与我的Azure数据库配合使用了好几天。

为了更清晰明确,以下是翻译内容:
  1. 数据库在Azure上,但Web应用程序是本地还是Azure上?
  2. 您不会使用OWIN将Web应用程序连接到数据库,而是尝试使用AspIdentity,这是应用程序成员身份系统的OWIN中间件。
  3. 您能否简单地针对数据库运行CREATE表,完全独立于AspIdentity,使用标准ADO.NET和您的连接字符串,例如在Home/Index操作中。即确定这是否与AspIdentity有任何关系,而不仅仅是Azure设置。
- rism
2个回答

9
我曾经遇到过类似的问题。
实体框架(Entity Framework)的 __MigrationHistory 列表包含 GZip 压缩后的数据。如果该列中的数据被损坏,您的应用程序将无法解压数据,从而导致错误出现。
在我的情况下,这种损坏是由于尝试手动插入该列表引起的。
我的解决方案:删除损坏的 __MigrationHistory 行和相关的数据库更改,并允许应用程序正确地迁移数据库。

有没有办法追踪数据库迁移表中哪一行数据出现了损坏? - Malik Khalil
@malik 或许尝试一次只更新一个迁移,看看哪一个可以成功。 - Mr. Flibble
我现在在将新更改推送到生产环境时遇到了同样的问题。然而,本地我使用 Code-First Migrations,而手动插入 SQL 脚本。有什么建议吗? - jmckie
你是如何发现哪些行已经损坏的? - Transformer

0

这是我的“理论”。我认为Sql Azure Db没有正确设置或连接字符串有误。

我们知道,当AspIdentity尝试在登录时访问数据库并发现表未设置时,它将尝试创建它们。

我认为,在这种情况下,AspIdentity代码存在故障/错误,会吞噬由错误的连接字符串生成的异常,因此无法完成设置并继续尝试向客户端提供身份验证票据。

如果我们查看Microsoft.Owin.Security.DataHandler.Serializer.TicketSerializer的代码,我们会发现一些GZip操作:

 public virtual byte[] Serialize(AuthenticationTicket model)
        {
            using (var memory = new MemoryStream())
            {
                using (var compression = new GZipStream(memory, CompressionLevel.Optimal))
                {
                    using (var writer = new BinaryWriter(compression))
                    {
                        Write(writer, model);
                    }
                }
                return memory.ToArray();
            }
        }

基本上,我认为AspIdentity在连接方面失败了,这个错误被吞噬了,Owin管道继续处理请求,但当它到达 TicketSerializer 时,可能会传递一个空值或其他一些虚假值,Gzip尝试压缩并Boom!

接着出现了奇怪的YSOD输出。

GZip头中的魔数不正确。请确保您正在传递GZip流。描述:当前Web请求执行期间发生未处理的异常。请查看堆栈跟踪以获取有关错误的更多信息以及其在代码中的起源。

对于这种特定事件,AspIdentity没有正确地短路OWIN请求处理。

可能是完全胡说八道,但我还是要提出来。


这些线索让我尝试了许多不同的选项,现在它已经可以工作了。我仍然不完全理解为什么会出错,但似乎与数据库登录有关。感谢您所有的建议。 :) - iCollect.it Ltd

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接