Configure ASP.Net core application with Hangfire

Tags: #<Tag:0x00007f53411c39c8>

I have an ASP.Net Core application which is working with Hangfire. I am now trying to configure Authorization with Hangfire in production based on the documentation here but I am getting a 403 error in production. What am I missing?

public void ConfigureServices(IServiceCollection services)
        {
            services.AddHttpContextAccessor();
            services.AddCors(options =>
            {
                options.AddPolicy(
                    "AllowAny",
                    x =>
                    {
                        x.AllowAnyHeader()
                        .AllowAnyMethod()
                        .SetIsOriginAllowed(isOriginAllowed: _ => true)
                        .AllowCredentials();
                    });
            });
            services.AddOData();
            services.AddODataQueryFilter();
            services.AddDbContext<ApplicationIdentityDbContext>(options =>
            {
                options.UseMySql(Configuration.GetConnectionString("InstaTranscribeDBConnection"));
            });
            services.AddIdentity<ApplicationUser, IdentityRole>()
                .AddRoles<IdentityRole>()
                .AddRoleStore<RoleStore<IdentityRole, ApplicationIdentityDbContext, string>>()
                .AddRoleManager<RoleManager<IdentityRole>>()
                .AddDefaultTokenProviders()
                .AddEntityFrameworkStores<ApplicationIdentityDbContext>();
            services.AddIdentityServer().AddApiAuthorization<ApplicationUser, ApplicationIdentityDbContext>();
            services.AddTransient<IdentityServer4.Services.IProfileService, ProfileService>();
            services.AddAuthentication().AddIdentityServerJwt();
            services.AddDbContext<InstaTranscribe.Data.InstaTranscribeDbContext>(options =>
            {
              options.UseMySql(Configuration.GetConnectionString("InstaTranscribeDBConnection"));
            });
            services.AddControllersWithViews();
            services.AddRazorPages();
            #region Add Hangfire services
            var connectionstring=Configuration.GetConnectionString("InstaTranscribeDBConnection");
            var hangfireConnectionstring = $"{connectionstring};Allow User Variables=true";
            var mySqlStorageOptions = new MySqlStorageOptions
            {
              TransactionIsolationLevel = (System.Transactions.IsolationLevel?)IsolationLevel.ReadCommitted,
              QueuePollInterval = TimeSpan.FromSeconds(15),
              JobExpirationCheckInterval = TimeSpan.FromHours(1),
              CountersAggregateInterval = TimeSpan.FromMinutes(5),
              PrepareSchemaIfNecessary = true,
              DashboardJobListLimit = 50000,
              TransactionTimeout = TimeSpan.FromMinutes(1),
              TablesPrefix = "Hangfire"
            };
            var mySqlStorage = new MySqlStorage(hangfireConnectionstring, mySqlStorageOptions);
            services.AddHangfire(config => config.UseStorage(mySqlStorage));
            services.AddHangfireServer();
            #endregion

        }
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ApplicationIdentityDbContext identityDbContext)
        {
.........code edited for brevity
            app.UseHttpsRedirection();
            app.UseBlazorFrameworkFiles();
            app.UseStaticFiles();            
            app.UseRouting();
            app.UseIdentityServer();
            app.UseAuthentication();
            app.UseAuthorization();
            //UseAuthentication, UseAuthorization should be before UseHangfireDashboard
            var dashboardOptions=new DashboardOptions()
            {
              Authorization = new[] { new HangFireJwtAuthorizationFilter() }
            };
            app.UseHangfireDashboard();
            IServiceProvider provider = app.ApplicationServices.GetRequiredService<IServiceProvider>();
            app.UseCors("AllowAny");
            app.UseEndpoints(endpoints =>
            {
.........code edited for brevity
              endpoints.MapHangfireDashboard("/hangfire", dashboardOptions);
            });
        }
public class HangFireJwtAuthorizationFilter : IDashboardAuthorizationFilter
  {
public HangFireJwtAuthorizationFilter()
{
}
public bool Authorize([NotNull] DashboardContext dashboardContext)
{      
  return true;
}
  }

Hi, this 403 is not generated by the Cors.

You need to add this in order to anable the acces when depoy into the server

Import this Nuget package

´´´
Install-Package Hangfire.Dashboard.BasicAuthorization
´´´
then change the Startup.cs to use this code cha

´´´
var dashboardOptions = new DashboardOptions
{
DashboardTitle = “WebHook Hub - HangFire”,
Authorization = new[] { new BasicAuthAuthorizationFilter(new BasicAuthAuthorizationFilterOptions
{
RequireSsl = false,
SslRedirect = false,
LoginCaseSensitive = true,
Users = new []
{
new BasicAuthAuthorizationUser
{
Login = “user”,
PasswordClear = “pass”
}
}
}) }
};
app.UseHangfireDashboard("/hangfire"), dashboardOptions);
´´´
Best regards
Gon

Hi ajitgoel,

you don’t need the below line

when you’re using the MapHangfireDashboard line below

try removing the first.