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