Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is Hangfire requiring authentication to view dashboard

Tags:

I am running HangFire within my MVC web app but whenever I try to navigate to http://MyApp/hangfire, it redirects me to my app's login page as though I am not logged in.

I have not explicitly configured any requirements for authorization...e.g. I had the below in the web.config, but then took it out in attempts to get this to work.

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

In theory, this is what I'd want, and when I log into my main web application, I will be logged in with an Administrator role so this rule should work.

But whether I have that configured in the web.config or not, whenever I try to navigate to http://MyApp/hangfire, it redirects me to my apps login page as configured in the web.config:

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

It does NOT do this on my local machine, just when I publish to my host. Does HangFire not recognize the authentication cookie that my main app provides when I login? I thought in general, the hangfire app doesn't require authentication, so what other configuration could be thinking that it does?

UPDATE 1:

I added the authorization filters per the hangfire docs, but the same thing happens. Here is my code in 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();
        }
    }
}

UPDATE 2:

Per the more detailed instructions showing basic authentication, I also tried this...still no luck..redirects me to my app's login page.

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"
            }
        }
    }));          
like image 986
crichavin Avatar asked Apr 04 '15 01:04

crichavin


People also ask

Why should I restrict access to the Hangfire dashboard?

For Hangfire Dashboard, it exposes sensitive information about your background jobs, including method names and serialized arguments as well as gives you an opportunity to manage them by performing different actions – retry, delete, trigger, etc. So it is really important to restrict access to the Dashboard.

How to set up a hangfire dashboard for a production server?

I just set up a Hangfire dashboard for our .NET Core application. As a security measure, the hangfire dashboard only allows local requests. If you wish to access the dashboard on a production server, you need to set up some form of Authorization by creating an implementation of IDashboardAuthorizationFilter.

Can Hangfire throw an exception when authentication is not set up?

It would be better for Hangfire to throw an exception when the authentication is not set up yet or warn when the authorization filters are applied. Can I customize the dashboard, suppose I want to add few controls like to Pause/Resume buttons for the running job or adding real time progress bar for each job.

How do I view the dashboard in Hangfire?

After performing these steps, open your browser and hit the http://<your-app>/hangfire URL to see the Dashboard. By default Hangfire allows access to Dashboard pages only for local requests.


2 Answers

With the newer versions you should use IDashboardAuthorizationFilter. With the using statements, it will look like this:

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; 
        }
    }
}

then in the configuration section:

app.UseHangfireDashboard("/jobs", new DashboardOptions() 
      {
          Authorization = new [] {new HangFireAuthorizationFilter()}
      });
like image 103
Baris Avatar answered Nov 21 '22 09:11

Baris


Finally got it working. I created my own AuthorizationFilter class (see below). Then I passed that to the MapHangfireDashboard method in the Startup.cs Configuration method (see below that)

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;
    }
}

To map hangfire to a custom url and specify the AuthorizationFilter to use:

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() });

}
like image 41
crichavin Avatar answered Nov 21 '22 09:11

crichavin