Due to the sensitive and very powerful nature of data and functionality in the Hangfire Dashboard, it is imperative that it is secured. You can do this by adding Authorization Filters as part of Hangfire’s initial configuration.

A problem occurs, however, when you try and get the HttpContext, but the User property always returns that IsAuthenticated is false, typically because you are using an alternative authentication/authorization scheme.

Whilst implementing Taggloo v4, I created my own IDashboardAuthorizationFilter that uses the Authentication Scheme used by the rest of the user-interface for the application. Based on the code at https://github.com/HangfireIO/Hangfire/issues/1039#issuecomment-457942078, I developed the following:

public class RoleAuthorizationFilter : IDashboardAuthorizationFilter
{
    public bool Authorize(DashboardContext context)
    {   
        // Attempt to authenticate against Identity.Application scheme.
        // This will attempt to authenticate using data in request, but doesn't send challenge.
        HttpContext? httpContext = context.GetHttpContext();
        if (httpContext == null) return false;
        
        AuthenticateResult result = httpContext.AuthenticateAsync("Identity.Application").Result;
        if (!result.Succeeded)
        {
            // Request was not authenticated
            return false;
        }

        var isAuthenticated = result.Principal?.Identity?.IsAuthenticated ?? false;
        if (isAuthenticated == false)
        {
            httpContext.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
        }

        bool isInRole=(result.Principal?.IsInRole("administrator")) ?? false;
        return isInRole;
    }
}

This can be integrated into the Dashboard Authorization in the Program class:

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

The IDashboardAuthorizationFilter simply uses an alternative authorization scheme, in this case, “Identity.Application”. Based on this, we can check the authentication status and the Role membership, and return an appropriate result.

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Quote of the era

In the beginning there was Jack … and Jack had a groove. And from this groove came the groove of all grooves. And while one day viciously throwing down on his box, Jack boldly declared “Let There Be House” and House music was born.

~ Chuck Roberts