20

我在我的 MVC Web 应用程序中运行 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:

根据显示基本身份验证的更详细说明,我也尝试了这个......仍然没有运气......将我重定向到我的应用程序的登录页面。

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"
            }
        }
    }));          
4

3 回答 3

40

对于较新的版本,您应该使用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()}
      });
于 2016-08-11T07:15:19.800 回答
16

终于让它工作了。我创建了自己的 AuthorizationFilter 类(见下文)。然后我将它传递给 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() });

}
于 2015-04-04T23:52:31.580 回答
3

正如我相信的那样。
请参阅仪表板的文档

默认情况下,Hangfire 仅允许本地请求访问仪表板页面。

奇怪的是,前几天我正在处理这个问题,需要注意的一件事是,如果您使用Autofac依赖注入,那么您需要确保以正确的顺序配置项目。特别是在其他身份验证之后的Hangfire ,而且在我的情况下,MembershipReboot 其他 OAuth 之前。
花了相当多的试验和错误。

于 2015-04-04T16:33:06.817 回答