diff --git a/framework/src/Volo.Abp.Features/Volo.Abp.Features.csproj b/framework/src/Volo.Abp.Features/Volo.Abp.Features.csproj
index 3bea3ea77f..9eb41af729 100644
--- a/framework/src/Volo.Abp.Features/Volo.Abp.Features.csproj
+++ b/framework/src/Volo.Abp.Features/Volo.Abp.Features.csproj
@@ -23,6 +23,7 @@
+
diff --git a/framework/src/Volo.Abp.Features/Volo/Abp/Features/AbpFeaturesModule.cs b/framework/src/Volo.Abp.Features/Volo/Abp/Features/AbpFeaturesModule.cs
index 70c6e7f37d..6793cd3990 100644
--- a/framework/src/Volo.Abp.Features/Volo/Abp/Features/AbpFeaturesModule.cs
+++ b/framework/src/Volo.Abp.Features/Volo/Abp/Features/AbpFeaturesModule.cs
@@ -1,6 +1,7 @@
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
+using Volo.Abp.Authorization;
using Volo.Abp.Features.Localization;
using Volo.Abp.Localization;
using Volo.Abp.Localization.ExceptionHandling;
@@ -14,7 +15,8 @@ namespace Volo.Abp.Features
[DependsOn(
typeof(AbpLocalizationModule),
typeof(AbpMultiTenancyModule),
- typeof(AbpValidationModule)
+ typeof(AbpValidationModule),
+ typeof(AbpAuthorizationModule)
)]
public class AbpFeaturesModule : AbpModule
{
diff --git a/framework/src/Volo.Abp.Features/Volo/Abp/Features/PermissionDefinitionExtensions.cs b/framework/src/Volo.Abp.Features/Volo/Abp/Features/PermissionDefinitionExtensions.cs
new file mode 100644
index 0000000000..a880fd85ff
--- /dev/null
+++ b/framework/src/Volo.Abp.Features/Volo/Abp/Features/PermissionDefinitionExtensions.cs
@@ -0,0 +1,14 @@
+using Volo.Abp.Authorization.Permissions;
+
+namespace Volo.Abp.Features
+{
+ public static class FeatureDefinitionExtensions
+ {
+ public static void RequireFeatures(this PermissionDefinition permissionDefinition, params string[] features)
+ {
+ Check.NotNullOrEmpty(features, nameof(features));
+
+ permissionDefinition.AddStateProvider(new RequireFeaturesPermissionStateProvider(features));
+ }
+ }
+}
diff --git a/framework/src/Volo.Abp.Features/Volo/Abp/Features/RequireFeaturesPermissionStateProvider.cs b/framework/src/Volo.Abp.Features/Volo/Abp/Features/RequireFeaturesPermissionStateProvider.cs
new file mode 100644
index 0000000000..93c8287cae
--- /dev/null
+++ b/framework/src/Volo.Abp.Features/Volo/Abp/Features/RequireFeaturesPermissionStateProvider.cs
@@ -0,0 +1,25 @@
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using Microsoft.Extensions.DependencyInjection;
+using Volo.Abp.Authorization.Permissions;
+
+namespace Volo.Abp.Features
+{
+ public class RequireFeaturesPermissionStateProvider : IPermissionStateProvider
+ {
+ private readonly List _requireFeatures = new List();
+
+ public RequireFeaturesPermissionStateProvider(params string[] requireFeatures)
+ {
+ Check.NotNullOrEmpty(requireFeatures, nameof(requireFeatures));
+
+ _requireFeatures.AddRange(requireFeatures);
+ }
+
+ public async Task IsEnabledAsync(PermissionStateContext context)
+ {
+ var feature = context.ServiceProvider.GetRequiredService();
+ return await feature.IsEnabledAsync(true, _requireFeatures.ToArray());
+ }
+ }
+}
diff --git a/framework/src/Volo.Abp.GlobalFeatures/Volo.Abp.GlobalFeatures.csproj b/framework/src/Volo.Abp.GlobalFeatures/Volo.Abp.GlobalFeatures.csproj
index a082ba3c6f..76ed80c497 100644
--- a/framework/src/Volo.Abp.GlobalFeatures/Volo.Abp.GlobalFeatures.csproj
+++ b/framework/src/Volo.Abp.GlobalFeatures/Volo.Abp.GlobalFeatures.csproj
@@ -23,6 +23,7 @@
+
diff --git a/framework/src/Volo.Abp.GlobalFeatures/Volo/Abp/GlobalFeatures/AbpGlobalFeaturesModule.cs b/framework/src/Volo.Abp.GlobalFeatures/Volo/Abp/GlobalFeatures/AbpGlobalFeaturesModule.cs
index b861fd7693..c381dd1c04 100644
--- a/framework/src/Volo.Abp.GlobalFeatures/Volo/Abp/GlobalFeatures/AbpGlobalFeaturesModule.cs
+++ b/framework/src/Volo.Abp.GlobalFeatures/Volo/Abp/GlobalFeatures/AbpGlobalFeaturesModule.cs
@@ -1,4 +1,5 @@
using Microsoft.Extensions.DependencyInjection;
+using Volo.Abp.Authorization;
using Volo.Abp.GlobalFeatures.Localization;
using Volo.Abp.Localization;
using Volo.Abp.Localization.ExceptionHandling;
@@ -9,7 +10,8 @@ namespace Volo.Abp.GlobalFeatures
{
[DependsOn(
typeof(AbpLocalizationModule),
- typeof(AbpVirtualFileSystemModule)
+ typeof(AbpVirtualFileSystemModule),
+ typeof(AbpAuthorizationModule)
)]
public class AbpGlobalFeaturesModule : AbpModule
{
diff --git a/framework/src/Volo.Abp.GlobalFeatures/Volo/Abp/GlobalFeatures/GlobalFeatureDefinitionExtensions.cs b/framework/src/Volo.Abp.GlobalFeatures/Volo/Abp/GlobalFeatures/GlobalFeatureDefinitionExtensions.cs
new file mode 100644
index 0000000000..b9896fb9a2
--- /dev/null
+++ b/framework/src/Volo.Abp.GlobalFeatures/Volo/Abp/GlobalFeatures/GlobalFeatureDefinitionExtensions.cs
@@ -0,0 +1,14 @@
+using Volo.Abp.Authorization.Permissions;
+
+namespace Volo.Abp.GlobalFeatures
+{
+ public static class GlobalFeatureDefinitionExtensions
+ {
+ public static void RequireGlobalFeatures(this PermissionDefinition permissionDefinition, params string[] globalFeatures)
+ {
+ Check.NotNullOrEmpty(globalFeatures, nameof(globalFeatures));
+
+ permissionDefinition.AddStateProvider(new RequireGlobalFeaturesPermissionStateProvider(globalFeatures));
+ }
+ }
+}
diff --git a/framework/src/Volo.Abp.GlobalFeatures/Volo/Abp/GlobalFeatures/RequireGlobalFeaturesPermissionStateProvider.cs b/framework/src/Volo.Abp.GlobalFeatures/Volo/Abp/GlobalFeatures/RequireGlobalFeaturesPermissionStateProvider.cs
new file mode 100644
index 0000000000..b7aea021c9
--- /dev/null
+++ b/framework/src/Volo.Abp.GlobalFeatures/Volo/Abp/GlobalFeatures/RequireGlobalFeaturesPermissionStateProvider.cs
@@ -0,0 +1,24 @@
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Volo.Abp.Authorization.Permissions;
+
+namespace Volo.Abp.GlobalFeatures
+{
+ public class RequireGlobalFeaturesPermissionStateProvider : IPermissionStateProvider
+ {
+ private readonly List _requireGlobalFeatures = new List();
+
+ public RequireGlobalFeaturesPermissionStateProvider(params string[] requireGlobalFeatures)
+ {
+ Check.NotNullOrEmpty(requireGlobalFeatures, nameof(requireGlobalFeatures));
+
+ _requireGlobalFeatures.AddRange(requireGlobalFeatures);
+ }
+
+ public Task IsEnabledAsync(PermissionStateContext context)
+ {
+ return Task.FromResult(_requireGlobalFeatures.All(x => GlobalFeatureManager.Instance.IsEnabled(x)));
+ }
+ }
+}