为什么 Hangfire 需要身份验证才能查看仪表板

Why is Hangfire requiring authentication to view dashboard

我在我的 MVC 网络应用程序中使用 运行 HangFire,但每当我尝试导航到 http://MyApp/hangfire 时,它都会将我重定向到我的应用程序的登录页面,就好像我没有登录一样。

我没有明确配置任何授权要求...例如我在 web.config 中有以下内容,但后来为了让它发挥作用而将其取出。

<location path="hangfire">
<system.web>
  <authorization>
    <allow roles="Administrator" />
    <deny users="*" />  
  </authorization>
</system.web>

理论上,这就是我想要的,当我登录到我的主 Web 应用程序时,我将以 Administrator 角色登录,因此这条规则应该有效。

但是无论我是否在 web.config 中进行了配置,每当我尝试导航到 http://MyApp/hangfire 时,它都会将我重定向到我在 web.config 中配置的应用程序登录页面:

<authentication mode="Forms">
  <forms loginUrl="~/Account/Login" timeout="960" />
</authentication>

它不会在我的本地机器上执行此操作,只是当我发布到我的主机时。当我登录时,HangFire 是否无法识别我的主应用程序提供的身份验证 cookie?我想一般来说,hangfire 应用程序不需要身份验证,那么还有什么其他配置可以认为它需要?

更新 1:

我根据 hangfire docs 添加了授权过滤器,但同样的事情发生了。这是我在 Startup.cs:

中的代码
using Hangfire;
using Hangfire.Logging;
using Hangfire.Dashboard;
using Hangfire.SqlServer;
using Microsoft.Owin;
using OTIS.Web.AppCode;
using OTISScheduler.AppServ;
using Owin;
using System.Web.Security;

[assembly: OwinStartup(typeof(OTIS.Web.App_Start.Startup))]
namespace OTIS.Web.App_Start
{
    public class Startup
    {
        public void Configuration(IAppBuilder app) {

            app.UseHangfire(config => {
                config.UseSqlServerStorage("DefaultConnection");
                config.UseServer();

                //Dashboard authorization
                config.UseAuthorizationFilters(new AuthorizationFilter
                {
                    Users = "USERA", // allow only specified users (comma delimited list)
                    Roles = "Account Administrator, Administrator" // allow only specified roles(comma delimited list)
                });


            });

            LogProvider.SetCurrentLogProvider(new StubLogProviderForHangfire());

            GlobalJobFilters.Filters.Add(new AutomaticRetryAttribute { Attempts = 0 });

            var scheduleTasksInitializer = new ScheduleTasksInitializer();

            scheduleTasksInitializer.ScheduleTasks();
        }
    }
}

更新 2:

根据更多 detailed instructions showing basic authentication,我也尝试了这个...仍然没有运气..将我重定向到我的应用程序的登录页面。

config.UseAuthorizationFilters(
new BasicAuthAuthorizationFilter(
    new BasicAuthAuthorizationFilterOptions
    {
        // Require secure connection for dashboard
        RequireSsl = false,
        SslRedirect = false,

        // Case sensitive login checking
        LoginCaseSensitive = true,

        // Users
        Users = new[]
        {
            new BasicAuthAuthorizationUser
            {
                Login = "MyLogin",

                // Password as plain text
                PasswordClear = "MyPwd"
            }
        }
    }));          

我相信是设计好的。
参见docs for the dashboard

By default Hangfire allows access to Dashboard pages only for local requests.

奇怪的是,前几天我正在处理这个问题,需要注意的一件事是,如果您在 Autofac dependency injection then you need to make sure you configure items in the correct order. Specifically Hangfire after other authentication but also, in my case, MembershipReboot 之前使用其他 OAuth 内容。
经过大量的反复试验。

终于成功了。我创建了自己的 AuthorizationFilter class(见下文)。 然后我将其传递给 Startup.cs 配置方法中的 MapHangfireDashboard 方法(见下文)

public class HangFireAuthorizationFilter : IAuthorizationFilter
{
    public bool Authorize(IDictionary<string, object> owinEnvironment)
    {
        bool boolAuthorizeCurrentUserToAccessHangFireDashboard = false;

        if (HttpContext.Current.User.Identity.IsAuthenticated)
        {
            if(HttpContext.Current.User.IsInRole("Account Administrator"))
                boolAuthorizeCurrentUserToAccessHangFireDashboard = true;
        }

        return boolAuthorizeCurrentUserToAccessHangFireDashboard;
    }
}

将 hangfire 映射到自定义 url 并指定要使用的 AuthorizationFilter:

public void Configuration(IAppBuilder app) {

    //Get from web.config to determine to fire up hangfire scheduler or not

    app.UseHangfire(config => {
        config.UseSqlServerStorage("DefaultConnection");
        config.UseServer();              
    });

    //map hangfire to a url and specify the authorization filter to use to allow access
    app.MapHangfireDashboard("/Admin/jobs", new[] { new HangFireAuthorizationFilter() });

}

对于较新的版本,您应该使用 IDashboardAuthorizationFilter。使用 using 语句,它将如下所示:

using System.Web;
using Hangfire.Annotations;
using Hangfire.Dashboard;

namespace Scheduler.Hangfire
{
    public class HangFireAuthorizationFilter : IDashboardAuthorizationFilter
    {
        public bool Authorize([NotNull] DashboardContext context)
        {
            //can add some more logic here...
            return HttpContext.Current.User.Identity.IsAuthenticated;

            //Can use this for NetCore
            return context.GetHttpContext().User.Identity.IsAuthenticated; 
        }
    }
}

然后在配置部分:

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