From 69fdb530a25ab1f018aec45b3aa161d3274ce488 Mon Sep 17 00:00:00 2001 From: Berkan Sasmaz Date: Fri, 30 Jul 2021 16:24:29 +0300 Subject: [PATCH 1/4] feat(Volo.Abp.HangFire): Add dashboard authorization for Hangfire --- .../Volo.Abp.HangFire.csproj | 1 + .../AbpHangfireAuthorizationFilter.cs | 46 +++++++++++++++++++ .../Volo/Abp/Hangfire/AbpHangfireModule.cs | 2 + 3 files changed, 49 insertions(+) create mode 100644 framework/src/Volo.Abp.HangFire/Volo/Abp/Hangfire/AbpHangfireAuthorizationFilter.cs diff --git a/framework/src/Volo.Abp.HangFire/Volo.Abp.HangFire.csproj b/framework/src/Volo.Abp.HangFire/Volo.Abp.HangFire.csproj index 4ec9d0a3b5..6b598d0edd 100644 --- a/framework/src/Volo.Abp.HangFire/Volo.Abp.HangFire.csproj +++ b/framework/src/Volo.Abp.HangFire/Volo.Abp.HangFire.csproj @@ -19,6 +19,7 @@ + diff --git a/framework/src/Volo.Abp.HangFire/Volo/Abp/Hangfire/AbpHangfireAuthorizationFilter.cs b/framework/src/Volo.Abp.HangFire/Volo/Abp/Hangfire/AbpHangfireAuthorizationFilter.cs new file mode 100644 index 0000000000..15fbb4f60c --- /dev/null +++ b/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 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(); + return currentUser.IsAuthenticated; + } + + private static async Task IsPermissionGrantedAsync(DashboardContext context, string requiredPermissionName) + { + var permissionChecker = context.GetHttpContext().RequestServices.GetRequiredService(); + return await permissionChecker.IsGrantedAsync(requiredPermissionName); + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.HangFire/Volo/Abp/Hangfire/AbpHangfireModule.cs b/framework/src/Volo.Abp.HangFire/Volo/Abp/Hangfire/AbpHangfireModule.cs index d69edb0b5d..1628d2f37f 100644 --- a/framework/src/Volo.Abp.HangFire/Volo/Abp/Hangfire/AbpHangfireModule.cs +++ b/framework/src/Volo.Abp.HangFire/Volo/Abp/Hangfire/AbpHangfireModule.cs @@ -1,10 +1,12 @@ using Hangfire; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; +using Volo.Abp.Authorization; using Volo.Abp.Modularity; namespace Volo.Abp.Hangfire { + [DependsOn(typeof(AbpAuthorizationAbstractionsModule))] public class AbpHangfireModule : AbpModule { private BackgroundJobServer _backgroundJobServer; From 1f5b6046887be689f2b71e67110515586f5c4d2f Mon Sep 17 00:00:00 2001 From: Berkan Sasmaz Date: Fri, 30 Jul 2021 16:36:02 +0300 Subject: [PATCH 2/4] docs: update Background-Jobs-Hangfire document for dashboard authorization feature --- docs/en/Background-Jobs-Hangfire.md | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/docs/en/Background-Jobs-Hangfire.md b/docs/en/Background-Jobs-Hangfire.md index cfa2e12a6b..6414f81c0e 100644 --- a/docs/en/Background-Jobs-Hangfire.md +++ b/docs/en/Background-Jobs-Hangfire.md @@ -79,3 +79,31 @@ After you have installed these NuGet packages, you need to configure your projec } ```` + +### Dashboard Authorization + +Hangfire can show a **dashboard page** so you can see the status of all background +jobs in real time. You can configure it as described in its +[documentation](http://docs.hangfire.io/en/latest/configuration/using-dashboard.html). +By default, this dashboard page is available for all users, and is not +authorized. You can integrate it in to ABP's [authorization +system](Authorization.md) using the **AbpHangfireAuthorizationFilter** +class defined in the Abp.HangFire package. Example configuration: + + app.UseHangfireDashboard("/hangfire", new DashboardOptions + { + AsyncAuthorization = new[] { new AbpHangfireAuthorizationFilter() } + }); + +This checks if the current user has logged in to the application. If you +want to require an additional permission, you can pass into its +constructor: + + app.UseHangfireDashboard("/hangfire", new DashboardOptions + { + AsyncAuthorization = new[] { new AbpHangfireAuthorizationFilter("MyHangFireDashboardPermissionName") } + }); + +**Note**: UseHangfireDashboard should be called after the authentication +middleware in your Startup class (probably as the last line). Otherwise, +authorization will always fail. From 956a6aed6305bde218d0ed7d7d245e4593695f2a Mon Sep 17 00:00:00 2001 From: Berkan Sasmaz Date: Fri, 30 Jul 2021 16:44:50 +0300 Subject: [PATCH 3/4] Update Background-Jobs-Hangfire.md --- docs/en/Background-Jobs-Hangfire.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/Background-Jobs-Hangfire.md b/docs/en/Background-Jobs-Hangfire.md index 6414f81c0e..952dc62880 100644 --- a/docs/en/Background-Jobs-Hangfire.md +++ b/docs/en/Background-Jobs-Hangfire.md @@ -88,7 +88,7 @@ jobs in real time. You can configure it as described in its By default, this dashboard page is available for all users, and is not authorized. You can integrate it in to ABP's [authorization system](Authorization.md) using the **AbpHangfireAuthorizationFilter** -class defined in the Abp.HangFire package. Example configuration: +class defined in the Volo.Abp.Hangfire package. Example configuration: app.UseHangfireDashboard("/hangfire", new DashboardOptions { From d9a2e41a7b14d39e4395879f798d188c12f6a808 Mon Sep 17 00:00:00 2001 From: ebicoglu Date: Sat, 31 Jul 2021 20:03:29 +0300 Subject: [PATCH 4/4] Update Background-Jobs-Hangfire.md --- docs/en/Background-Jobs-Hangfire.md | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/docs/en/Background-Jobs-Hangfire.md b/docs/en/Background-Jobs-Hangfire.md index 952dc62880..a690d9d17b 100644 --- a/docs/en/Background-Jobs-Hangfire.md +++ b/docs/en/Background-Jobs-Hangfire.md @@ -82,28 +82,23 @@ After you have installed these NuGet packages, you need to configure your projec ### Dashboard Authorization -Hangfire can show a **dashboard page** so you can see the status of all background -jobs in real time. You can configure it as described in its -[documentation](http://docs.hangfire.io/en/latest/configuration/using-dashboard.html). -By default, this dashboard page is available for all users, and is not -authorized. You can integrate it in to ABP's [authorization -system](Authorization.md) using the **AbpHangfireAuthorizationFilter** -class defined in the Volo.Abp.Hangfire package. Example configuration: +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() } }); -This checks if the current user has logged in to the application. If you -want to require an additional permission, you can pass into its -constructor: +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") } }); -**Note**: UseHangfireDashboard should be called after the authentication -middleware in your Startup class (probably as the last line). Otherwise, -authorization will always fail. +**Important**: `UseHangfireDashboard` should be called after the authentication middleware in your `Startup` class (probably at the last line). Otherwise, +authorization will always fail!