We were unable to load Disqus. If you are a moderator please see our troubleshooting guide.
Hello Ankit! Glad to hear that :) Thank you
Hi Sahan, This solution is great and it works in .netCore 3.1 but I am working with .net 5 and the method .AddAzureAD is obsolete. Could you please update the solution for .net 5?
I couldn't find the way to make it work :(
Thanks!
Hi! Do you know by chance how to reuse existing IdentityServer4 jwt authentication? I want my currently authenticated user in Angular front-end to be considered in Hangfire dashboard as well - without need to sign in there again. I thought I would need to save current access token in cookies, but cannot manage to do that (don't know the suitable place).
Hello Sahan,
I am able to configure my asp.net core application to work with Hangfire but authorization is not working. I am assuming that I have not configured my application to use the correct authentication scheme when adding authorization.
Can you please provide your input? I have also posted the question in SO here.
public partial class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
string handfirepolicyname="HangfirePolicyName";
public void ConfigureServices(IServiceCollection services)
{
...Code removed for brevity
services.AddAuthentication().AddIdentityServerJwt();
services.AddAuthorization(options =>
{
options.AddPolicy(handfirepolicyname, builder =>
{ builder.AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme).RequireAuthenticatedUser();
builder.RequireRole("admin");
});
});
var hangfireConnectionstring = "SomeHangfireDatabaseConnectionString";
var mySqlStorageOptions = new MySqlStorageOptions();
var mySqlStorage = new MySqlStorage(hangfireConnectionstring, mySqlStorageOptions);
services.AddHangfire(config => config.UseStorage(mySqlStorage));
services.AddHangfireServer();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ApplicationIdentityDbContext identityDbContext)
{
...Code removed for brevity
app.UseIdentityServer();
app.UseAuthentication();
app.UseAuthorization();
//UseAuthentication, UseAuthorization should be before UseHangfireDashboard
app.UseHangfireDashboard();
app.UseEndpoints(endpoints =>
{
endpoints.MapHangfireDashboard("/hangfire", new DashboardOptions()
{
Authorization = new List<idashboardauthorizationfilter> { }
}).RequireAuthorization(handfirepolicyname);
});
}
Error:
No authentication handler is registered for the scheme 'Bearer'. The registered schemes are: Identity.Application, Identity.External, Identity.TwoFactorRememberMe, Identity.TwoFactorUserId, idsrv, idsrv.external, IdentityServerJwt, IdentityServerJwtBearer. Did you forget to call AddAuthentication().Add[SomeAuthHandler]("Bearer",...)?
You have this: AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme)
JwtBearerDefaults.AuthenticationScheme == 'Bearer', but you don't utilize this scheme. From your code, I can see you use app.UseIdentityServer() and this extension uses some other scheme name - one from your list. It could be 'idsrv' or other. Not sure...
Hi Sahan,
I have tested your solution on my asp.net core 3.1 mvc application but when I try to open the dashboard URL seems the policy doesn't fired: It allow me to see the dashboard without authentication. Have some suggestion?
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(AzureADDefaults.AuthenticationScheme)
.AddAzureAD(options => Configuration.Bind("AzureAd", options));
services.AddControllersWithViews(options =>
{
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
options.Filters.Add(new AuthorizeFilter(policy));
});
services.AddRazorPages();
//HANGFIRE
services.AddAuthorization(options =>
{
// Policy to be applied to hangfire endpoint
options.AddPolicy(HANGFIREPOLICY, builder =>
{
builder
.AddAuthenticationSchemes(AzureADDefaults.AuthenticationScheme)
.RequireAuthenticatedUser();
});
});
...
//HANGFIRE
// Add Hangfire services.
services.AddHangfire(configuration => configuration
.SetDataCompatibilityLevel(CompatibilityLevel.Version_170)
.UseSimpleAssemblyNameTypeSerializer()
.UseRecommendedSerializerSettings()
.UseSqlServerStorage(Configuration.GetConnectionString("HangfireConnection"), new SqlServerStorageOptions
{
CommandBatchMaxTimeout = TimeSpan.FromMinutes(5),
SlidingInvisibilityTimeout = TimeSpan.FromMinutes(5),
QueuePollInterval = TimeSpan.Zero,
UseRecommendedIsolationLevel = true,
UsePageLocksOnDequeue = true,
DisableGlobalLocks = true
}));
// Add the processing server as IHostedService
services.AddHangfireServer(opt => opt.SchedulePollingInterval = TimeSpan.FromMinutes(1));
}
...
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IServiceProvider serviceProvider)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
//HANGFIRE
app.UseHangfireDashboard();
// HANGFIRE Configure endpoints
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
endpoints.MapRazorPages();
endpoints.MapHangfireDashboard("/hangfire", new DashboardOptions()
{
Authorization = new List<idashboardauthorizationfilter> { }
})
.RequireAuthorization(HANGFIREPOLICY);
});
}
Thank you
Hey Luca,
I had a quick look at what you posted and it seems like you are missing the following lines in Configure() method:
...
app.UseAuthentication();
app.UseAuthorization();
...
You need these before the app.UseHangfireDashboard(); line
I have updated my repo with an example for MVC as well. Have a look and let me know:
I have miss something in my copy and paste operation into the disquis editor 😅.
I already have UseAuthentication() and UseAuthorization() in my code, but I have looked at your Startup.cs code's and I have made an order mistake: I call UseHangfireDashboard() before UseAuthorization(). Now seems work well.
Thank you for your feedback
Yes, the order of those statement matters and it's very easy to miss them. No problem. Glad to help you resolve your issue! 😀
Hello Sahan, I was looking for a solution like this since couple of days.
Works like a charm.
Thanks