Hangfire 仪表板更复杂的身份验证

时间:2021-03-24 14:53:23

标签: asp.net hangfire

我在应用程序上使用 hangfire,我需要使用我的存储库进行仪表板身份验证。为此,我必须在 Hangfire 的 Authorize 方法中解析存储库,但是使用 OwinContext 我一直无法这样做。我选择在这个项目中使用 SimpleInjector,因为它在 WebApiConfigRegister 方法中注册了所有东西,所以我想访问它。最近我使用了一个 middleware 作为 MessageHandler,然后我成功地使用 HttpRequestMessage 解决了一个依赖项。但是在 OwinContext 上,我无法使用 HttpRequestMessage.GetDependencyScope() 访问它并通过它解决依赖项。

这是 Hangfire 建议在其文档中对 Asp.net 应用进行身份验证的方式;

public class MyAuthorizationFilter : IDashboardAuthorizationFilter
{
    public bool Authorize(DashboardContext context)
    {
        // In case you need an OWIN context, use the next line, `OwinContext` class
        // is the part of the `Microsoft.Owin` package.
        var owinContext = new OwinContext(context.GetOwinEnvironment());

        // Allow all authenticated users to see the Dashboard (potentially dangerous).
        return owinContext.Authentication.User.Identity.IsAuthenticated;
    }
}

由于我在前端使用 Angular,因此 owinContext.Authentication.User 为空。即使不是这样,我也只希望自己够到仪表板。所以这不能解决我的问题。

如何在 Authorize 方法中解决我的依赖关系?

我不能通过构造函数注入来做到这一点,因为对于 Hangfire,你在 UseHangfireDashboardStartup.cs 上说 Configuration 如下所述;

这是我的 Startup.cs 文件

private IEnumerable<IDisposable> GetHangfireServers()
{
    Hangfire.GlobalConfiguration.Configuration
        .SetDataCompatibilityLevel(CompatibilityLevel.Version_170)
        .UseSimpleAssemblyNameTypeSerializer()
        .UseRecommendedSerializerSettings()
        .UseSqlServerStorage("CONN_STR", new SqlServerStorageOptions
        {
            CommandBatchMaxTimeout = TimeSpan.FromMinutes(5),
            SlidingInvisibilityTimeout = TimeSpan.FromMinutes(5),
            QueuePollInterval = TimeSpan.Zero,
            UseRecommendedIsolationLevel = true,
            DisableGlobalLocks = true
        });

    yield return new BackgroundJobServer();
}

public void Configuration(IAppBuilder app)
{
    app.UseHangfireAspNet(GetHangfireServers);
    app.UseHangfireDashboard("/hangfire", new DashboardOptions { 
        Authorization = new [] { 
            new DashboardAuthorization() 
            /* explanation */ 
            // for DI to work through constructor, 
            //I have to give my AuthRepository as a parameter here. 
            //And my AuthRepository also has many DIs so, 
            //it's not possible through here.
        }
    });

    BackgroundJob.Enqueue(() => Console.WriteLine("Hello world from Hangfire!"));

}

顺便说一下,我的项目是一个 .Net Framework 4.7.2 项目。

1 个答案:

答案 0 :(得分:1)

就 Hangfire 而言,您负责提供实现 IDashboardAuthorizationFilter 的类的实例。因此,如果该类具有您要注入的依赖项,则需要您进行连接。最好在您的 DI 容器中注册该类型及其依赖项,并让它为您解析一个实例。这样它就可以通过构造函数注入为您注入所有依赖项。

您应该在 Startup.cs 中得到类似这样的模式,您可以在其中配置 OWIN 管道。

public void Configuration(IAppBuilder app)
{
    var container = CreateContainerWithRegisteredServices();
    var dashboardFilter = container.Resolve<IDashboardAuthorizationFilter>();

    app.UseHangfireDashboard("/hangfire", new DashboardOptions { 
        Authorization = new [] { dashboardFilter }
    });

    BackgroundJob.Enqueue(() => Console.WriteLine("Hello world from Hangfire!"));

    // Configure Web API, SignalR, or whatever else hangs off your OWIN pipeline.
    // You can pass the container into their configure methods if necessary.   
}

IContainer CreateContainerWithRegisteredServices()
{
    //this method will look different depending on your chosen IoC library
    var container = SomeIoCLibrary.CreateContainer();
    container.Register<MyAuthorizationFilter, IDashboardAuthorizationFilter>();
    //register other dependencies here

    return container;
}