Browse Source

Merge pull request #424 from colinin/4.4.3

fix(hangfire): 修复Hangfire仪表板权限问题
pull/426/head
yx lin 4 years ago
committed by GitHub
parent
commit
db834df0d4
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 13
      aspnet-core/modules/common/LINGYUN.Abp.Hangfire.Dashboard/LINGYUN.Abp.Hangfire.Dashboard.csproj
  2. 16
      aspnet-core/modules/common/LINGYUN.Abp.Hangfire.Dashboard/LINGYUN/Abp/Hangfire/Dashboard/AbpHangfireDashboardModule.cs
  3. 21
      aspnet-core/modules/common/LINGYUN.Abp.Hangfire.Dashboard/LINGYUN/Abp/Hangfire/Dashboard/AbpHangfireDashboardOptionsProvider.cs
  4. 50
      aspnet-core/modules/common/LINGYUN.Abp.Hangfire.Dashboard/LINGYUN/Abp/Hangfire/Dashboard/Authorization/DashboardAuthorizationFilter.cs
  5. 48
      aspnet-core/modules/common/LINGYUN.Abp.Hangfire.Dashboard/LINGYUN/Abp/Hangfire/Dashboard/Authorization/DashboardPermissionChecker.cs
  6. 33
      aspnet-core/modules/common/LINGYUN.Abp.Hangfire.Dashboard/LINGYUN/Abp/Hangfire/Dashboard/Authorization/HangfireDashboardPermissionDefinitionProvider.cs
  7. 15
      aspnet-core/modules/common/LINGYUN.Abp.Hangfire.Dashboard/LINGYUN/Abp/Hangfire/Dashboard/Authorization/HangfireDashboardPermissions.cs
  8. 10
      aspnet-core/modules/common/LINGYUN.Abp.Hangfire.Dashboard/LINGYUN/Abp/Hangfire/Dashboard/Authorization/IDashboardPermissionChecker.cs
  9. 9
      aspnet-core/modules/common/LINGYUN.Abp.Hangfire.Dashboard/LINGYUN/Abp/Hangfire/Dashboard/Localization/HangfireDashboardResource.cs
  10. 7
      aspnet-core/modules/common/LINGYUN.Abp.Hangfire.Dashboard/LINGYUN/Abp/Hangfire/Dashboard/Localization/Resources/en.json
  11. 7
      aspnet-core/modules/common/LINGYUN.Abp.Hangfire.Dashboard/LINGYUN/Abp/Hangfire/Dashboard/Localization/Resources/zh-Hans.json
  12. 2
      aspnet-core/modules/common/LINGYUN.Abp.Hangfire.Dashboard/Microsoft/AspNetCore/Http/HangfireAuthoricationMiddleware.cs
  13. 3
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application.Contracts/LINGYUN/Abp/MessageService/Localization/ApplicationContracts/en.json
  14. 3
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application.Contracts/LINGYUN/Abp/MessageService/Localization/ApplicationContracts/zh-Hans.json
  15. 2
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application.Contracts/LINGYUN/Abp/MessageService/Permissions/MessageServicePermissions.cs
  16. 1
      aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application.Contracts/LINGYUN/Abp/MessageService/Permissions/MessageServicePermissionsDefinitionProvider.cs
  17. 18
      aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/AbpMessageServiceHttpApiHostModule.Configure.cs
  18. 2
      aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/AbpMessageServiceHttpApiHostModule.cs
  19. 4
      aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/LINGYUN.Abp.MessageService.HttpApi.Host.csproj

13
aspnet-core/modules/common/LINGYUN.Abp.Hangfire.Dashboard/LINGYUN.Abp.Hangfire.Dashboard.csproj

@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\common.props" />
@ -7,18 +7,9 @@
<RootNamespace />
</PropertyGroup>
<ItemGroup>
<None Remove="LINGYUN\Abp\Hangfire\Dashboard\Localization\Resources\en.json" />
<None Remove="LINGYUN\Abp\Hangfire\Dashboard\Localization\Resources\zh-Hans.json" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="LINGYUN\Abp\Hangfire\Dashboard\Localization\Resources\en.json" />
<EmbeddedResource Include="LINGYUN\Abp\Hangfire\Dashboard\Localization\Resources\zh-Hans.json" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Volo.Abp.Authorization" Version="4.4.0" />
<PackageReference Include="Volo.Abp.Caching" Version="4.4.0" />
<PackageReference Include="Volo.Abp.Hangfire" Version="4.4.0" />
</ItemGroup>

16
aspnet-core/modules/common/LINGYUN.Abp.Hangfire.Dashboard/LINGYUN/Abp/Hangfire/Dashboard/AbpHangfireDashboardModule.cs

@ -1,31 +1,17 @@
using LINGYUN.Abp.Hangfire.Dashboard.Localization;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Authorization;
using Volo.Abp.Hangfire;
using Volo.Abp.Localization;
using Volo.Abp.Modularity;
using Volo.Abp.VirtualFileSystem;
namespace LINGYUN.Abp.Hangfire.Dashboard
{
[DependsOn(
typeof(AbpLocalizationModule),
typeof(AbpAuthorizationModule),
typeof(AbpHangfireModule))]
public class AbpHangfireDashboardModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpVirtualFileSystemOptions>(options =>
{
options.FileSets.AddEmbedded<AbpHangfireDashboardModule>();
});
Configure<AbpLocalizationOptions>(options =>
{
options.Resources.Add<HangfireDashboardResource>();
});
context.Services.AddTransient(serviceProvider =>
{
var options = serviceProvider.GetRequiredService<AbpHangfireDashboardOptionsProvider>().Get();

21
aspnet-core/modules/common/LINGYUN.Abp.Hangfire.Dashboard/LINGYUN/Abp/Hangfire/Dashboard/AbpHangfireDashboardOptionsProvider.cs

@ -1,10 +1,5 @@
using Hangfire;
using Hangfire.Dashboard;
using LINGYUN.Abp.Hangfire.Dashboard.Authorization;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Authorization.Permissions;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Threading;
namespace LINGYUN.Abp.Hangfire.Dashboard
{
@ -12,21 +7,7 @@ namespace LINGYUN.Abp.Hangfire.Dashboard
{
public virtual DashboardOptions Get()
{
return new DashboardOptions
{
Authorization = new IDashboardAuthorizationFilter[]
{
new DashboardAuthorizationFilter()
},
IsReadOnlyFunc = (context) =>
{
var httpContext = context.GetHttpContext();
var permissionChecker = httpContext.RequestServices.GetRequiredService<IPermissionChecker>();
return !AsyncHelper.RunSync(async () =>
await permissionChecker.IsGrantedAsync(HangfireDashboardPermissions.Dashboard.ManageJobs));
}
};
return new DashboardOptions();
}
}
}

50
aspnet-core/modules/common/LINGYUN.Abp.Hangfire.Dashboard/LINGYUN/Abp/Hangfire/Dashboard/Authorization/DashboardAuthorizationFilter.cs

@ -1,32 +1,46 @@
using Hangfire.Annotations;
using Hangfire.Dashboard;
using Hangfire.Dashboard;
using Microsoft.Extensions.DependencyInjection;
using System.Linq;
using Volo.Abp.Authorization.Permissions;
using Volo.Abp.Threading;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Volo.Abp.Users;
namespace LINGYUN.Abp.Hangfire.Dashboard.Authorization
{
public class DashboardAuthorizationFilter : IDashboardAuthorizationFilter
public class DashboardAuthorizationFilter : IDashboardAsyncAuthorizationFilter
{
internal readonly static string[] AllowRoutePrefixs = new string[]
private readonly string[] _requiredPermissionNames;
public DashboardAuthorizationFilter(params string[] requiredPermissionNames)
{
_requiredPermissionNames = requiredPermissionNames;
}
public async Task<bool> AuthorizeAsync(DashboardContext context)
{
"/stats",
"/js",
"/css",
"/fonts"
};
public bool Authorize([NotNull] DashboardContext context)
if (!IsLoggedIn(context))
{
if (AllowRoutePrefixs.Any(url => context.Request.Path.StartsWith(url)))
return false;
}
if (_requiredPermissionNames.IsNullOrEmpty())
{
return true;
}
var httpContext = context.GetHttpContext();
var permissionChecker = httpContext.RequestServices.GetRequiredService<IPermissionChecker>();
return AsyncHelper.RunSync(async () =>
await permissionChecker.IsGrantedAsync(httpContext.User, HangfireDashboardPermissions.Dashboard.Default));
return await IsPermissionGrantedAsync(context, _requiredPermissionNames);
}
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[] requiredPermissionNames)
{
var permissionChecker = context.GetHttpContext().RequestServices.GetRequiredService<IDashboardPermissionChecker>();
return await permissionChecker.IsGrantedAsync(context, requiredPermissionNames);
}
}
}

48
aspnet-core/modules/common/LINGYUN.Abp.Hangfire.Dashboard/LINGYUN/Abp/Hangfire/Dashboard/Authorization/DashboardPermissionChecker.cs

@ -0,0 +1,48 @@
using Hangfire.Dashboard;
using Microsoft.Extensions.Caching.Memory;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Volo.Abp.Authorization.Permissions;
using Volo.Abp.DependencyInjection;
namespace LINGYUN.Abp.Hangfire.Dashboard.Authorization
{
public class DashboardPermissionChecker : IDashboardPermissionChecker, ITransientDependency
{
// 仪表板属于高频访问, 设定有效期的二级权限缓存
private readonly IMemoryCache _memoryCache;
private readonly IPermissionChecker _permissionChecker;
public DashboardPermissionChecker(
IMemoryCache memoryCache,
IPermissionChecker permissionChecker)
{
_memoryCache = memoryCache;
_permissionChecker = permissionChecker;
}
public virtual async Task<bool> IsGrantedAsync(DashboardContext context, string[] requiredPermissionNames)
{
var localPermissionKey = $"_HDPS:{requiredPermissionNames.JoinAsString(";")}";
if (_memoryCache.TryGetValue(localPermissionKey, out MultiplePermissionGrantResult cacheItem))
{
return cacheItem.AllGranted;
}
cacheItem = await _permissionChecker.IsGrantedAsync(requiredPermissionNames);
_memoryCache.Set(
localPermissionKey,
cacheItem,
new MemoryCacheEntryOptions
{
// 5分钟过期
AbsoluteExpiration = DateTimeOffset.Now.AddMinutes(5d),
});
return cacheItem.AllGranted;
}
}
}

33
aspnet-core/modules/common/LINGYUN.Abp.Hangfire.Dashboard/LINGYUN/Abp/Hangfire/Dashboard/Authorization/HangfireDashboardPermissionDefinitionProvider.cs

@ -1,33 +0,0 @@
using LINGYUN.Abp.Hangfire.Dashboard.Localization;
using Volo.Abp.Authorization.Permissions;
using Volo.Abp.Localization;
using Volo.Abp.MultiTenancy;
namespace LINGYUN.Abp.Hangfire.Dashboard.Authorization
{
public class HangfireDashboardPermissionDefinitionProvider : PermissionDefinitionProvider
{
public override void Define(IPermissionDefinitionContext context)
{
var group = context.AddGroup(
HangfireDashboardPermissions.GroupName,
L("Permission:Hangfire"),
MultiTenancySides.Host); // 除非对Hangfire Api进行改造,否则不能区分租户
var dashboard = group.AddPermission(
HangfireDashboardPermissions.Dashboard.Default,
L("Permission:Dashboard"),
MultiTenancySides.Host);
dashboard.AddChild(
HangfireDashboardPermissions.Dashboard.ManageJobs,
L("Permission:ManageJobs"),
MultiTenancySides.Host);
}
private static LocalizableString L(string name)
{
return LocalizableString.Create<HangfireDashboardResource>(name);
}
}
}

15
aspnet-core/modules/common/LINGYUN.Abp.Hangfire.Dashboard/LINGYUN/Abp/Hangfire/Dashboard/Authorization/HangfireDashboardPermissions.cs

@ -1,15 +0,0 @@
namespace LINGYUN.Abp.Hangfire.Dashboard.Authorization
{
public static class HangfireDashboardPermissions
{
public const string GroupName = "Hangfire";
public static class Dashboard
{
public const string Default = GroupName + ".Dashboard";
public const string ManageJobs = Default + ".ManageJobs";
// TODO: other pages...
}
}
}

10
aspnet-core/modules/common/LINGYUN.Abp.Hangfire.Dashboard/LINGYUN/Abp/Hangfire/Dashboard/Authorization/IDashboardPermissionChecker.cs

@ -0,0 +1,10 @@
using Hangfire.Dashboard;
using System.Threading.Tasks;
namespace LINGYUN.Abp.Hangfire.Dashboard.Authorization
{
public interface IDashboardPermissionChecker
{
Task<bool> IsGrantedAsync(DashboardContext context, string[] requiredPermissionNames);
}
}

9
aspnet-core/modules/common/LINGYUN.Abp.Hangfire.Dashboard/LINGYUN/Abp/Hangfire/Dashboard/Localization/HangfireDashboardResource.cs

@ -1,9 +0,0 @@
using Volo.Abp.Localization;
namespace LINGYUN.Abp.Hangfire.Dashboard.Localization
{
[LocalizationResourceName("HangfireDashboard")]
public class HangfireDashboardResource
{
}
}

7
aspnet-core/modules/common/LINGYUN.Abp.Hangfire.Dashboard/LINGYUN/Abp/Hangfire/Dashboard/Localization/Resources/en.json

@ -1,7 +0,0 @@
{
"culture": "en",
"texts": {
"Permission:Hangfire": "Hangfire",
"Permission:Dashboard": "Dashboard"
}
}

7
aspnet-core/modules/common/LINGYUN.Abp.Hangfire.Dashboard/LINGYUN/Abp/Hangfire/Dashboard/Localization/Resources/zh-Hans.json

@ -1,7 +0,0 @@
{
"culture": "zh-Hans",
"texts": {
"Permission:Hangfire": "Hangfire",
"Permission:Dashboard": "仪表板"
}
}

2
aspnet-core/modules/common/LINGYUN.Abp.Hangfire.Dashboard/Microsoft/AspNetCore/Http/HangfireAuthoricationMiddleware.cs

@ -7,7 +7,7 @@ namespace Microsoft.AspNetCore.Http
{
public async Task InvokeAsync(HttpContext context, RequestDelegate next)
{
// 通过 iframe 加载页面的话,需要手动传递 access_token 到参数列表
// 通过 iframe 加载页面的话,初次传递 access_token 到 QueryString
if (context.Request.Path.StartsWithSegments("/hangfire") &&
context.User.Identity?.IsAuthenticated != true)
{

3
aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application.Contracts/LINGYUN/Abp/MessageService/Localization/ApplicationContracts/en.json

@ -4,7 +4,8 @@
"Permission:MessageService": "Message service",
"Permission:Notification": "Notification",
"Permission:Delete": "Delete",
"Permission:Hangfire": "Hangfire dashboard",
"Permission:Hangfire": "Hangfire",
"Permission:Dashboard": "Dashboard",
"Permission:ManageQueue": "Manage queue"
}
}

3
aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application.Contracts/LINGYUN/Abp/MessageService/Localization/ApplicationContracts/zh-Hans.json

@ -4,7 +4,8 @@
"Permission:MessageService": "消息服务",
"Permission:Notification": "通知管理",
"Permission:Delete": "删除",
"Permission:Hangfire": "Hangfire仪表板",
"Permission:Hangfire": "Hangfire",
"Permission:Dashboard": "仪表板",
"Permission:ManageQueue": "管理队列"
}
}

2
aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application.Contracts/LINGYUN/Abp/MessageService/Permissions/MessageServicePermissions.cs

@ -15,6 +15,8 @@
{
public const string Default = GroupName + ".Hangfire";
public const string Dashboard = Default + ".Dashboard";
public const string ManageQueue = Default + ".ManageQueue";
}
}

1
aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application.Contracts/LINGYUN/Abp/MessageService/Permissions/MessageServicePermissionsDefinitionProvider.cs

@ -14,6 +14,7 @@ namespace LINGYUN.Abp.MessageService.Permissions
noticeGroup.AddChild(MessageServicePermissions.Notification.Delete, L("Permission:Delete"));
var hangfirePermission = group.AddPermission(MessageServicePermissions.Hangfire.Default, L("Permission:Hangfire"));
hangfirePermission.AddChild(MessageServicePermissions.Hangfire.Dashboard, L("Permission:Dashboard"));
hangfirePermission.AddChild(MessageServicePermissions.Hangfire.ManageQueue, L("Permission:ManageQueue"));
}

18
aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/AbpMessageServiceHttpApiHostModule.Configure.cs

@ -1,7 +1,10 @@
using DotNetCore.CAP;
using Hangfire.Dashboard;
using LINGYUN.Abp.ExceptionHandling;
using LINGYUN.Abp.Hangfire.Dashboard.Authorization;
using LINGYUN.Abp.Localization.CultureMap;
using LINGYUN.Abp.MessageService.Localization;
using LINGYUN.Abp.MessageService.Permissions;
using LINGYUN.Abp.Serilog.Enrichers.Application;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Cors;
@ -27,6 +30,8 @@ using Volo.Abp.Localization;
using Volo.Abp.MultiTenancy;
using Volo.Abp.VirtualFileSystem;
using HangfireDashboardOptions = Hangfire.DashboardOptions;
namespace LINGYUN.Abp.MessageService
{
public partial class AbpMessageServiceHttpApiHostModule
@ -53,6 +58,19 @@ namespace LINGYUN.Abp.MessageService
});
}
private void PreCongifureHangfire()
{
PreConfigure<HangfireDashboardOptions>(options =>
{
options.AsyncAuthorization = new IDashboardAsyncAuthorizationFilter[]
{
new DashboardAuthorizationFilter(
MessageServicePermissions.Hangfire.Dashboard,
MessageServicePermissions.Hangfire.ManageQueue)
};
});
}
private void ConfigureDbContext()
{
// 配置Ef

2
aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/AbpMessageServiceHttpApiHostModule.cs

@ -77,6 +77,7 @@ namespace LINGYUN.Abp.MessageService
var configuration = context.Services.GetConfiguration();
PreConfigureApp();
PreCongifureHangfire();
PreConfigureCAP(configuration);
}
@ -110,6 +111,7 @@ namespace LINGYUN.Abp.MessageService
// 跨域
app.UseCors(DefaultCorsPolicyName);
app.UseSignalRJwtToken();
app.UseHangfireAuthorication();
// 认证
app.UseAuthentication();
app.UseAbpClaimsMap();

4
aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/LINGYUN.Abp.MessageService.HttpApi.Host.csproj

@ -71,4 +71,8 @@
<ProjectReference Include="..\..\..\modules\wechat\LINGYUN.Abp.Notifications.WeChat.MiniProgram\LINGYUN.Abp.Notifications.WeChat.MiniProgram.csproj" />
</ItemGroup>
<ItemGroup>
<Folder Include="Logs\" />
</ItemGroup>
</Project>

Loading…
Cancel
Save