We were unable to load Disqus. If you are a moderator please see our troubleshooting guide.

Ankit Srivastava • 5 years ago

Hello Sahan, I was looking for a solution like this since couple of days.
Works like a charm.
Thanks

Sahan Serasinghe • 5 years ago

Hello Ankit! Glad to hear that :) Thank you

Argentinian DEV • 5 years ago

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!

Alexander • 5 years ago

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).

Ajit Goel • 5 years ago

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",...)?

Alexander • 5 years ago

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...

Luca • 5 years ago

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

Sahan Serasinghe • 5 years ago

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:

https://github.com/sahan91/...

Luca • 5 years ago

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

Sahan Serasinghe • 5 years ago

Yes, the order of those statement matters and it's very easy to miss them. No problem. Glad to help you resolve your issue! 😀