I have an ASP.NET Core 2.0 app that uses the Hangfire Dashboard. When running it in my localhost (IIS Express), everything works fine but when it is deployed live as a Dockerized app the Hangfire Dashboard page just returns a β403β error.
Is there a specific configuration I need to do when deploying it as a Dockerized app?
This is from my Startup
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseBrowserLink();
app.UseDatabaseErrorPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
}
app.UseStaticFiles();
app.UseAuthentication();
app.UseMvcWithDefaultRoute();
app.UseHangfireServer();
UseHangfireDashboardCustom(app);
RecurringJob.AddOrUpdate<IFacebookAdsCronJobService>("FacebookAdsInsights", c =>
c.Execute(),
Cron.Daily);
}
private static IApplicationBuilder UseHangfireDashboardCustom(
IApplicationBuilder app,
string pathMatch = "/romi/data-integration",
DashboardOptions options = null,
JobStorage storage = null)
{
var services = app.ApplicationServices;
storage = storage ?? services.GetRequiredService<JobStorage>();
options = options ?? services.GetService<DashboardOptions>() ?? new DashboardOptions();
var routes = app.ApplicationServices.GetRequiredService<RouteCollection>();
// Use our custom middleware.
app.Map(new PathString(pathMatch), x =>
x.UseMiddleware<HangfireDashboardMiddleware>(storage, options, routes)
);
return app;
}
This is the Middleware
using System.Linq;
using System.Net;
using System.Threading.Tasks;
using Hangfire;
using Hangfire.Dashboard;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Http;
namespace ROMI.DataIntegration.Web.Facebook.Ads.Auth
{
public class HangfireDashboardMiddleware
{
private readonly DashboardOptions _dashboardOptions;
private readonly JobStorage _jobStorage;
private readonly RequestDelegate _nextRequestDelegate;
private readonly RouteCollection _routeCollection;
public HangfireDashboardMiddleware(
RequestDelegate nextRequestDelegate,
JobStorage storage,
DashboardOptions options,
RouteCollection routes)
{
_nextRequestDelegate = nextRequestDelegate;
_jobStorage = storage;
_dashboardOptions = options;
_routeCollection = routes;
}
public async Task Invoke(HttpContext httpContext)
{
var aspNetCoreDashboardContext =
new AspNetCoreDashboardContext(_jobStorage, _dashboardOptions, httpContext);
var findResult = _routeCollection.FindDispatcher(httpContext.Request.Path.Value);
if (findResult == null)
{
await _nextRequestDelegate.Invoke(httpContext);
return;
}
// attempt to authenticate against default auth scheme (this will attempt to authenticate using data in request, but doesn't send challenge)
var result = await httpContext.AuthenticateAsync();
if (!httpContext.User.Identity.IsAuthenticated)
{
// request was not authenticated, send challenge and do not continue processing this request
await httpContext.ChallengeAsync();
}
if (_dashboardOptions
.Authorization
.Any(filter =>
filter.Authorize(aspNetCoreDashboardContext) == false))
{
var isAuthenticated = httpContext.User?.Identity?.IsAuthenticated;
httpContext.Response.StatusCode = isAuthenticated == true
? (int) HttpStatusCode.Forbidden
: (int) HttpStatusCode.Unauthorized;
return;
}
aspNetCoreDashboardContext.UriMatch = findResult.Item2;
await findResult.Item1.Dispatch(aspNetCoreDashboardContext);
}
}
}