Browse Source

Merge pull request #9704 from abpframework/berkan/hangfire-dashboard-permission

Add dashboard authorization for HangFire
pull/9706/head
ebicoglu 5 years ago
committed by GitHub
parent
commit
0bda7d8daf
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 23
      docs/en/Background-Jobs-Hangfire.md
  2. 1
      framework/src/Volo.Abp.HangFire/Volo.Abp.HangFire.csproj
  3. 46
      framework/src/Volo.Abp.HangFire/Volo/Abp/Hangfire/AbpHangfireAuthorizationFilter.cs
  4. 2
      framework/src/Volo.Abp.HangFire/Volo/Abp/Hangfire/AbpHangfireModule.cs

23
docs/en/Background-Jobs-Hangfire.md

@ -79,3 +79,26 @@ After you have installed these NuGet packages, you need to configure your projec
} }
```` ````
### Dashboard Authorization
Hangfire Dashboard provides information about your background jobs, including method names and serialized arguments as well as gives you an opportunity to manage them by performing different actions – retry, delete, trigger, etc. So it is important to restrict access to the Dashboard.
To make it secure by default, only local requests are allowed, however you can change this by following the [official documentation](http://docs.hangfire.io/en/latest/configuration/using-dashboard.html) of Hangfire.
You can integrate the Hangfire dashboard to [ABP authorization system](Authorization.md) using the **AbpHangfireAuthorizationFilter**
class. This class is defined in the `Volo.Abp.Hangfire` package. The following example, checks if the current user is logged in to the application:
app.UseHangfireDashboard("/hangfire", new DashboardOptions
{
AsyncAuthorization = new[] { new AbpHangfireAuthorizationFilter() }
});
If you want to require an additional permission, you can pass it into the constructor as below:
app.UseHangfireDashboard("/hangfire", new DashboardOptions
{
AsyncAuthorization = new[] { new AbpHangfireAuthorizationFilter("MyHangFireDashboardPermissionName") }
});
**Important**: `UseHangfireDashboard` should be called after the authentication middleware in your `Startup` class (probably at the last line). Otherwise,
authorization will always fail!

1
framework/src/Volo.Abp.HangFire/Volo.Abp.HangFire.csproj

@ -19,6 +19,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Volo.Abp.Authorization.Abstractions\Volo.Abp.Authorization.Abstractions.csproj" />
<ProjectReference Include="..\Volo.Abp.Core\Volo.Abp.Core.csproj" /> <ProjectReference Include="..\Volo.Abp.Core\Volo.Abp.Core.csproj" />
</ItemGroup> </ItemGroup>

46
framework/src/Volo.Abp.HangFire/Volo/Abp/Hangfire/AbpHangfireAuthorizationFilter.cs

@ -0,0 +1,46 @@
using System;
using System.Threading.Tasks;
using Hangfire.Dashboard;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Authorization.Permissions;
using Volo.Abp.Users;
namespace Volo.Abp.Hangfire
{
public class AbpHangfireAuthorizationFilter : IDashboardAsyncAuthorizationFilter
{
private readonly string _requiredPermissionName;
public AbpHangfireAuthorizationFilter(string requiredPermissionName = null)
{
_requiredPermissionName = requiredPermissionName;
}
public async Task<bool> AuthorizeAsync(DashboardContext context)
{
if (!IsLoggedIn(context))
{
return false;
}
if (_requiredPermissionName.IsNullOrEmpty())
{
return true;
}
return await IsPermissionGrantedAsync(context, _requiredPermissionName);
}
private static bool IsLoggedIn(DashboardContext context)
{
var currentUser = context.GetHttpContext().RequestServices.GetRequiredService<ICurrentUser>();
return currentUser.IsAuthenticated;
}
private static async Task<bool> IsPermissionGrantedAsync(DashboardContext context, string requiredPermissionName)
{
var permissionChecker = context.GetHttpContext().RequestServices.GetRequiredService<IPermissionChecker>();
return await permissionChecker.IsGrantedAsync(requiredPermissionName);
}
}
}

2
framework/src/Volo.Abp.HangFire/Volo/Abp/Hangfire/AbpHangfireModule.cs

@ -1,10 +1,12 @@
using Hangfire; using Hangfire;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Volo.Abp.Authorization;
using Volo.Abp.Modularity; using Volo.Abp.Modularity;
namespace Volo.Abp.Hangfire namespace Volo.Abp.Hangfire
{ {
[DependsOn(typeof(AbpAuthorizationAbstractionsModule))]
public class AbpHangfireModule : AbpModule public class AbpHangfireModule : AbpModule
{ {
private BackgroundJobServer _backgroundJobServer; private BackgroundJobServer _backgroundJobServer;

Loading…
Cancel
Save