如何在 ASP.NET Core 中使用 Hangfire 以及 Azure 数据库和 Active Directory 密码身份验证

Mic*_*zyn 5 azure-active-directory hangfire azure-sql-database asp.net-core-webapi hangfire-sql

我们正在尝试在 ASP.NET Core WebApi 应用程序 (.NET 5) 中首次使用 Hangfire (v1.7.19)。以前它们都是老式的 ASP.NET,并且运行没有问题。

使用的 Hangfire 软件包(根据Hangfire 文档)是Hangfire.CoreHangfire.SqlServerHangfire.AspNetCore。我们也尝试过仅使用组合Hangfire包,但得到了相同的结果。

直接从该文档页面上的代码中提取,在ConfigureServices中我们添加

    services.AddHangfire(configuration => configuration
        .SetDataCompatibilityLevel(CompatibilityLevel.Version_170)
        .UseSimpleAssemblyNameTypeSerializer()
        .UseRecommendedSerializerSettings()
        .UseSqlServerStorage(connectionString), new SqlServerStorageOptions
        {
            CommandBatchMaxTimeout = TimeSpan.FromMinutes(5),
            SlidingInvisibilityTimeout = TimeSpan.FromMinutes(5),
            QueuePollInterval = TimeSpan.Zero,
            UseRecommendedIsolationLevel = true,
            DisableGlobalLocks = true
        }));
Run Code Online (Sandbox Code Playgroud)

在运行时,给出

System.ArgumentException
  HResult=0x80070057
  Message=Keyword not supported: 'authentication'.
  Source=System.Data.SqlClient
  StackTrace:
   at System.Data.Common.DbConnectionOptions.ParseInternal(Dictionary`2 parsetable, String connectionString, Boolean buildChain, Dictionary`2 synonyms)
   at System.Data.Common.DbConnectionOptions..ctor(String connectionString, Dictionary`2 synonyms)
   at System.Data.SqlClient.SqlConnectionString..ctor(String connectionString)
   at System.Data.SqlClient.SqlConnectionFactory.CreateConnectionOptions(String connectionString, DbConnectionOptions previous)
   at System.Data.ProviderBase.DbConnectionFactory.GetConnectionPoolGroup(DbConnectionPoolKey key, DbConnectionPoolGroupOptions poolOptions, DbConnectionOptions& userConnectionOptions)
   at System.Data.SqlClient.SqlConnection.ConnectionString_Set(DbConnectionPoolKey key)
   at System.Data.SqlClient.SqlConnection.set_ConnectionString(String value)
   at System.Data.SqlClient.SqlConnection..ctor(String connectionString)
   at Hangfire.SqlServer.SqlServerStorage.<.ctor>b__6_0()
   at Hangfire.SqlServer.SqlServerStorage.CreateAndOpenConnection()
   at Hangfire.SqlServer.SqlServerStorage.UseConnection[T](DbConnection dedicatedConnection, Func`2 func)
   at Hangfire.SqlServer.SqlServerStorage.UseConnection(DbConnection dedicatedConnection, Action`1 action)
   at Hangfire.SqlServer.SqlServerStorage.Initialize()
   at Hangfire.SqlServer.SqlServerStorage..ctor(String nameOrConnectionString, SqlServerStorageOptions options)
   at Hangfire.SqlServer.SqlServerStorage..ctor(String nameOrConnectionString)
   at Hangfire.SqlServerStorageExtensions.UseSqlServerStorage(IGlobalConfiguration configuration, String nameOrConnectionString)
Run Code Online (Sandbox Code Playgroud)

connectionString的值为

Initial Catalog=XXX;Data Source=YYY;Authentication=Active Directory Password;UID=ZZZ;PWD=PPP"
Run Code Online (Sandbox Code Playgroud)

这适用于本地 SqlServer 和 LocalDb,但不适用于 AzureDB。连接字符串正是我们在 EntityFrameworkCore 5 中使用的字符串(事实上,该值是从 分配的context.Database.GetConnectionString())。

我读过 AzureDB 和 .NET Core 存在问题的地方,但这些问题很久以前就得到了解决。通过查看Hangfire.SqlServer包依赖项,我看到它在哪里使用System.Data.SqlClient,并且 AzureDB 的当前文档使用全部引用Microsoft.Data.SqlClient,这让我认为支持 Active Directory 密码身份验证的增强功能不是在较新的包System.Data.SqlClient中而是仅在较新的Microsoft.Data.SqlClient包中进行的。如果是这种情况,我可以提出请求,要求 Hangfire 替换其 SqlClient 包,但希望在执行此操作之前获得确认。

如果情况确实如此,有什么想法吗?与此同时,我们可以做些什么来解决这个问题吗?

提前致谢。

Tur*_*ass 4

Hangfire IO GitHub 问题 1827

谢尔盖·奥季诺科夫的指点

早在 1.7.8 就支持使用UseSqlServerStorage接受 a 的重载Func<DbConnection>而不是连接字符串,您可以使用连接工厂来提供Microsoft.Data.SqlClient.SqlConnection支持该Authentication关键字的更新版本。

这是相关的源码

你可以这样使用

 services.AddHangfire(config => config
       // other options you listed above removed for brevity
.UseSqlServerStorage(
          () => new Microsoft.Data.SqlClient.SqlConnection(<connection_string>)
          , new SqlServerStorageOptions() {...}
     )
);
Run Code Online (Sandbox Code Playgroud)