Browse Source

Enhance AbpHangfireAuthorizationFilter to support policy requirements

pull/23119/head
maliming 1 year ago
parent
commit
1493b3ff63
No known key found for this signature in database GPG Key ID: A646B9CB645ECEA4
  1. 16
      docs/en/framework/infrastructure/background-jobs/hangfire.md
  2. 50
      framework/src/Volo.Abp.HangFire/Volo/Abp/Hangfire/AbpHangfireAuthorizationFilter.cs

16
docs/en/framework/infrastructure/background-jobs/hangfire.md

@ -159,14 +159,24 @@ app.UseAbpHangfireDashboard("/hangfire", options =>
`AbpHangfireAuthorizationFilter` class has the following fields: `AbpHangfireAuthorizationFilter` class has the following fields:
* **`enableTenant` (`bool`, default: `false`):** Enables/disables accessing the Hangfire dashboard on tenant users. * **`enableTenant` (`bool`, default: `false`):** Enables/disables accessing the Hangfire dashboard on tenant users.
* **`requiredPermissionName` (`string`, default: `null`):** Hangfire dashboard is accessible only if the current user has the specified permission. In this case, if we specify a permission name, we don't need to set `enableTenant` `true` because the permission system already does it. * **`requiredPermissionName` (`string`, default: `null`):** Hangfire dashboard is accessible only if the current user has the specified permission.
* **`requiredRoleNames` (`string[]`, default: `null`):** Hangfire dashboard is accessible only if the current user has one of the specified roles.
If you want to require an additional permission, you can pass it into the constructor as below: If you want to require more policies you can use the `PolicyBuilder` property of the `AbpHangfireAuthorizationFilter` class.
```csharp ```csharp
app.UseAbpHangfireDashboard("/hangfire", options => app.UseAbpHangfireDashboard("/hangfire", options =>
{ {
options.AsyncAuthorization = new[] { new AbpHangfireAuthorizationFilter(requiredPermissionName: "MyHangFireDashboardPermissionName") }; var hangfireAuthorizationFilter = new AbpHangfireAuthorizationFilter(requiredPermissionName: "MyHangFireDashboardPermissionName");
//hangfireAuthorizationFilter.PolicyBuilder.RequireClaim("my_custom_claim", "my_custom_value");
//hangfireAuthorizationFilter.PolicyBuilder.RequireRole();
//hangfireAuthorizationFilter.PolicyBuilder.Requirements.Add(new YourCustomRequirement());
options.AsyncAuthorization = new[]
{
hangfireAuthorizationFilter
};
}); });
``` ```

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

@ -1,53 +1,49 @@
using System; using System;
using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using Hangfire.Dashboard; using Hangfire.Dashboard;
using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Authorization.Permissions; using Volo.Abp.Authorization;
using Volo.Abp.Users; using Volo.Abp.MultiTenancy;
namespace Volo.Abp.Hangfire; namespace Volo.Abp.Hangfire;
public class AbpHangfireAuthorizationFilter : IDashboardAsyncAuthorizationFilter public class AbpHangfireAuthorizationFilter : IDashboardAsyncAuthorizationFilter
{ {
private readonly bool _enableTenant; private readonly bool _enableTenant;
private readonly string? _requiredPermissionName; private readonly AuthorizationPolicyBuilder _policyBuilder;
public AbpHangfireAuthorizationFilter(bool enableTenant = false, string? requiredPermissionName = null) public virtual AuthorizationPolicyBuilder PolicyBuilder => _policyBuilder;
{
_enableTenant = requiredPermissionName.IsNullOrWhiteSpace() ? enableTenant : true;
_requiredPermissionName = requiredPermissionName;
}
public async Task<bool> AuthorizeAsync(DashboardContext context) public AbpHangfireAuthorizationFilter(bool enableTenant = false, string? requiredPermissionName = null, params string[]? requiredRoleNames)
{ {
if (!IsLoggedIn(context, _enableTenant)) _enableTenant = enableTenant;
_policyBuilder = new AuthorizationPolicyBuilder().RequireAuthenticatedUser();
if (!requiredPermissionName.IsNullOrWhiteSpace())
{ {
return false; _policyBuilder.Requirements.Add(new PermissionRequirement(requiredPermissionName));
} }
if (_requiredPermissionName.IsNullOrEmpty()) if (!requiredRoleNames.IsNullOrEmpty())
{ {
return true; foreach (var roleName in requiredRoleNames!)
{
_policyBuilder.RequireRole(roleName);
}
} }
return await IsPermissionGrantedAsync(context, _requiredPermissionName!);
} }
private static bool IsLoggedIn(DashboardContext context, bool enableTenant) public virtual async Task<bool> AuthorizeAsync(DashboardContext context)
{ {
var currentUser = context.GetHttpContext().RequestServices.GetRequiredService<ICurrentUser>(); var currentTenant = context.GetHttpContext().RequestServices.GetRequiredService<ICurrentTenant>();
if (currentTenant.IsAvailable && !_enableTenant)
if (!enableTenant)
{ {
return currentUser.IsAuthenticated && !currentUser.TenantId.HasValue; return false;
} }
return currentUser.IsAuthenticated; var authorizationService = context.GetHttpContext().RequestServices.GetRequiredService<IAuthorizationService>();
} var authorizationPolicy = _policyBuilder.Build();
return (await authorizationService.AuthorizeAsync(context.GetHttpContext().User, authorizationPolicy)).Succeeded;
private static async Task<bool> IsPermissionGrantedAsync(DashboardContext context, string requiredPermissionName)
{
var permissionChecker = context.GetHttpContext().RequestServices.GetRequiredService<IPermissionChecker>();
return await permissionChecker.IsGrantedAsync(requiredPermissionName);
} }
} }

Loading…
Cancel
Save