Barebones Authorization for Hangfire Dashboard
October 21, 2019
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. Now, there are a number of ways to do this, depending on your reuirements. All we needed was a quick solution that would allow us to see our dashboard on our development server.
If you are also looking for a quick and dirty solution,here is how I did it :
First, create an implementation of IDashboardAuthorizationFilter. We provide this implementation in the form of an Action Filter called HangfireAuthorizationFilter
You are now required to implement the Authorize method. We will authorize our user using credentials supplied in the query string. We simply store a username and password in our appsetting.json and correlate the supplied credentials with these stored credentials. If they match, we store them in a session cookie and return true, completing the Auth process.
Why do we need a cookie you say? thats because hangfire periodically makes requests to the application server in order to provide realtime data. Therefore, although the first request will contain the credentials in the query string, all subsequent calls will not, and hence, they will return a 401 status code. We fix this by including a session cookie in the reponse of our auth call. All subsequent requests made in that same session will contain this cookie and we can reauhtorize each incoming request.
public bool Authorize(DashboardContext context)
{
var httpContext = context.GetHttpContext();
string userName = _settings.UserName;
string password = _settings.Password;
//if user has already logged in, in this session, subsequent requests will read credentials from cookie
if (httpContext.Request.Cookies["user"] != null && httpContext.Request.Cookies["pwd"] != null
&& httpContext.Request.Cookies["user"].Equals(userName) && httpContext.Request.Cookies["pwd"].Equals(password)) {
return true;
}
else if (context.Request.GetQuery("user") != null && context.Request.GetQuery("pwd") != null
&& context.Request.GetQuery("user").Equals(userName) && context.Request.GetQuery("pwd").Equals(password))
{
//Store credentials in cookie so that subsequent requests dont require them
httpContext.Response.Cookies.Append("user", userName);
httpContext.Response.Cookies.Append("pwd", password);
return true;
}
else return false;
}
Next, simply include you implemenation of IDashboardAuthorizationFilter in your startup file and youre done.
app.UseHangfireDashboard("/hangfire", new DashboardOptions
{
IsReadOnlyFunc = (DashboardContext context) => _hangfireSettings.MakeDashboardReadonly,
Authorization = new[] { new HangFireAuthorizationFilter(_hangfireSettings)}
});