You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在ASP.NET Boilerplate中为组织单元指定特定功能

实现ABP组织单元级功能分配的FeatureProvider方案

首先得明确:ABP默认的Feature是租户/用户级的,要实现组织单元(OU)级的功能细分,我们需要自定义FeatureProvider,同时结合权限系统绑定OU和功能的关联。下面是具体落地步骤:

1. 自定义FeatureProvider定义核心功能

先创建一个继承自AbpFeatureProvider的类,在SetFeatures方法里定义租户级的基础功能(Product和Book),同时为每个需要OU控制的功能,通过Metadata标记对应的OU权限关联:

public class CustomFeatureProvider : AbpFeatureProvider
{
    public override void SetFeatures(IFeatureDefinitionContext context)
    {
        // 定义租户级基础功能开关
        var productFeature = context.Create("Product", defaultValue: "false")
            .WithDisplayName("产品模块功能")
            .WithDescription("为租户启用产品模块");

        var bookFeature = context.Create("Book", defaultValue: "false")
            .WithDisplayName("图书模块功能")
            .WithDescription("为租户启用图书模块");

        // 给每个功能绑定对应的OU级权限标识(存在Metadata里,后续检查用)
        productFeature.Metadata.Add("OuPermissionKey", "Product.OuAccess");
        bookFeature.Metadata.Add("OuPermissionKey", "Book.OuAccess");
    }
}

2. 定义组织单元级权限

在PermissionProvider里创建对应OU级的权限,用于控制某个OU是否能使用该功能:

public class CustomPermissionProvider : PermissionProvider
{
    public override void SetPermissions(IPermissionDefinitionContext context)
    {
        var productGroup = context.CreateGroup("Product", "产品模块权限组");
        productGroup.CreatePermission("Product.OuAccess", L("允许组织单元访问产品模块"));

        var bookGroup = context.CreateGroup("Book", "图书模块权限组");
        bookGroup.CreatePermission("Book.OuAccess", L("允许组织单元访问图书模块"));
    }

    private static ILocalizableString L(string name)
    {
        return new LocalizableString(name, YourProjectConsts.LocalizationSourceName);
    }
}

3. 扩展FeatureChecker实现OU级检查

重写ABP默认的FeatureChecker,在检查功能可用性时,除了验证租户的Feature开关,还要验证当前用户所在OU是否拥有对应的权限:

public class CustomFeatureChecker : FeatureChecker
{
    private readonly IPermissionChecker _permissionChecker;
    private readonly IOrganizationUnitUserRepository _ouUserRepo;

    public CustomFeatureChecker(
        IFeatureDefinitionManager featureDefinitionManager,
        ICurrentTenant currentTenant,
        IPermissionChecker permissionChecker,
        IOrganizationUnitUserRepository ouUserRepo) : base(featureDefinitionManager, currentTenant)
    {
        _permissionChecker = permissionChecker;
        _ouUserRepo = ouUserRepo;
    }

    public override async Task<bool> IsEnabledAsync(string name)
    {
        // 第一步:先检查租户是否开启了该功能
        var tenantEnabled = await base.IsEnabledAsync(name);
        if (!tenantEnabled)
            return false;

        // 第二步:从Feature元数据里获取对应的OU权限标识
        var feature = await FeatureDefinitionManager.GetAsync(name);
        if (!feature.Metadata.TryGetValue("OuPermissionKey", out var ouPermissionName))
            return true; // 没有标记OU权限的功能,直接返回可用

        // 第三步:检查当前用户所属的OU是否拥有该权限
        var currentUser = await CurrentUser.GetAsync();
        if (currentUser == null)
            return false;

        var userOus = await _ouUserRepo.GetListAsync(currentUser.Id);
        foreach (var ou in userOus)
        {
            if (await _permissionChecker.IsGrantedAsync(ou.OrganizationUnitId, ouPermissionName))
                return true;
        }

        return false;
    }
}

4. 替换默认FeatureChecker

在模块的ConfigureServices方法里,把ABP默认的FeatureChecker替换成我们自定义的:

public override void ConfigureServices(ServiceConfigurationContext context)
{
    // ...其他模块配置
    context.Services.Replace(ServiceDescriptor.Transient<IFeatureChecker, CustomFeatureChecker>());
}

5. 给组织单元分配权限

最后在管理后台添加操作界面,让管理员可以给指定组织单元分配Product.OuAccess或Book.OuAccess权限。当租户开启Product功能后,只有被分配了对应权限的OU下的用户,才能实际使用Product功能,完美实现你要的细分控制。

内容的提问来源于stack exchange,提问作者Edward

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 06:42:16