Galosys.Foundation.DataPermission 26.7.25.1

dotnet add package Galosys.Foundation.DataPermission --version 26.7.25.1
                    
NuGet\Install-Package Galosys.Foundation.DataPermission -Version 26.7.25.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Galosys.Foundation.DataPermission" Version="26.7.25.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Galosys.Foundation.DataPermission" Version="26.7.25.1" />
                    
Directory.Packages.props
<PackageReference Include="Galosys.Foundation.DataPermission" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Galosys.Foundation.DataPermission --version 26.7.25.1
                    
#r "nuget: Galosys.Foundation.DataPermission, 26.7.25.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Galosys.Foundation.DataPermission@26.7.25.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Galosys.Foundation.DataPermission&version=26.7.25.1
                    
Install as a Cake Addin
#tool nuget:?package=Galosys.Foundation.DataPermission&version=26.7.25.1
                    
Install as a Cake Tool

Galosys.Foundation.DataPermission

可扩展的行级数据权限框架,与 EF Core 全局查询过滤器深度集成。支持部门级、个人级、角色数据范围三种过滤策略,通过标记接口自动识别实体维度,零侵入实现数据隔离。

快速开始

1. 安装

在项目中引用 Galosys.Foundation.DataPermission(依赖 Core + EntityFrameworkCore)。

2. 注册服务(最小配置)

// Program.cs / Startup.cs
using Galosys.Foundation.DataPermission;

services.AddDataPermission(options =>
{
    options.AddFilter<DeptDataPermissionFilter>();     // 部门级过滤
    options.AddFilter<PersonalDataPermissionFilter>(); // 个人级过滤
    options.AddFilter<RoleDataScopeFilter>();          // 角色数据范围
});

3. 实现权限上下文

框架通过 IDataPermissionContext 获取当前用户信息,需由中台或业务层实现:

using Galosys.Foundation.DataPermission;

public class JwtDataPermissionContext : IDataPermissionContext
{
    public long UserId { get; }          // 当前用户ID
    public string? UserName { get; }     // 当前用户名称
    public long DeptId { get; }          // 当前用户所属部门ID
    public IReadOnlyList<long> RoleIds { get; }   // 当前用户角色ID列表
    public DataScope DataScope { get; }           // 数据权限范围
    public IReadOnlyList<long> DeptIds { get; }   // 授权可见的部门ID列表(含子部门树)

    public JwtDataPermissionContext(ClaimsPrincipal user)
    {
        UserId = user.FindFirst("sub")?.Let(long.Parse) ?? 0;
        UserName = user.FindFirst("name")?.Value;
        DeptId = user.FindFirst("dept_id")?.Let(long.Parse) ?? 0;
        RoleIds = user.FindAll("role_id").Select(c => long.Parse(c.Value)).ToList();
        DataScope = user.FindFirst("data_scope")?.Let(Enum.Parse<DataScope>) ?? DataScope.Personal;
        DeptIds = user.FindAll("dept_ids").Select(c => long.Parse(c.Value)).ToList();
    }
}

注册上下文(Scoped 生命周期,每个请求一份):

using Galosys.Foundation.DataPermission;
using Microsoft.AspNetCore.Http;

services.AddScoped<IDataPermissionContext>(sp =>
{
    var httpContext = sp.GetRequiredService<IHttpContextAccessor>().HttpContext;
    if (httpContext == null) return null!;  // BackgroundService 场景优雅降级,无过滤器生效
    return new JwtDataPermissionContext(httpContext.User);
});

4. 实体标记接口

为实体添加标记接口即可自动参与数据权限过滤:

using Galosys.Foundation.DataPermission;

// 同时支持部门级和个人级过滤
public class Order : FullEntity<long>, IDataPermissionDept, IDataPermissionCreator
{
    public long DeptId { get; set; }      // 部门ID(IDataPermissionDept 要求)
    public long CreatorId { get; set; }   // 创建人ID(IDataPermissionCreator 要求)
}

完成以上配置后,所有 EF Core 查询自动附加数据权限过滤,无需手动编写 Where 条件。


实体标记接口

接口 属性 说明
IDataPermissionDept DeptId 实体实现后支持按部门维度过滤
IDataPermissionCreator CreatorId 实体实现后支持按创建人维度过滤

实体可单独实现一个接口,也可同时实现两个。框架通过 isAssignable 检测自动选择对应的过滤器。


DataScope 数据范围

名称 过滤行为
All 全部数据 不添加任何过滤
Dept 本部门 e.DeptId == 当前部门ID
DeptAndChild 本部门及下属 DeptIds.Contains(e.DeptId)
Personal 仅本人 e.CreatorId == 当前用户ID
Custom 自定义 DeptIds.Contains(e.DeptId)(使用自定义的部门列表)

内置过滤器详解

DeptDataPermissionFilter(Order = 10)

部门级过滤器,处理 IDataPermissionDept 实体。

DataScope 行为
All 不过滤
Dept e => e.DeptId == context.DeptId
DeptAndChild / Custom e => context.DeptIds.Contains(e.DeptId)
Personal 不过滤(由 PersonalDataPermissionFilter 处理)

PersonalDataPermissionFilter(Order = 20)

个人级过滤器,仅在 DataScope.Personal 时生效,处理 IDataPermissionCreator 实体。

DataScope 行为
Personal e => e.CreatorId == context.UserId
其他 不过滤

RoleDataScopeFilter(Order = 5)

角色数据范围过滤器,优先级最高(Order 最小)。当 DataScope.Personal 且实体实现了 IDataPermissionCreator 时,按创建人过滤;DataScope.All 时不过滤。

三个过滤器通过 AndAlso 组合,最终生成一个统一的过滤表达式注入 EF Core 全局查询过滤器。


自定义过滤器

实现 IDataPermissionFilter 接口并注册即可扩展:

using Galosys.Foundation.DataPermission;
using System.Linq.Expressions;

/// <summary>
/// 按业务线过滤示例
/// </summary>
public class BusinessLineFilter : IDataPermissionFilter
{
    public int Order => 15;  // 执行顺序,介于 Dept(10) 和 Personal(20) 之间

    public Expression<Func<TEntity, bool>>? BuildFilter<TEntity>(IDataPermissionContext context)
        where TEntity : class
    {
        // 仅对实现了 IBusinessLine 接口的实体生效
        if (!typeof(IBusinessLine).IsAssignableFrom(typeof(TEntity)))
            return null;

        // 从上下文扩展信息中获取业务线
        var parameter = Expression.Parameter(typeof(TEntity), "e");
        var blProp = Expression.Property(parameter, nameof(IBusinessLine.BusinessLineId));
        var body = Expression.Equal(blProp, Expression.Constant(context.DeptId));

        return Expression.Lambda<Func<TEntity, bool>>(body, parameter);
    }
}

注册:

services.AddDataPermission(options =>
{
    options.AddFilter<RoleDataScopeFilter>();
    options.AddFilter<DeptDataPermissionFilter>();
    options.AddFilter<BusinessLineFilter>();       // 自定义过滤器
    options.AddFilter<PersonalDataPermissionFilter>();
});

架构说明

┌──────────────────────────────────────────────────────────┐
│                     EF Core DbContext                     │
│  ┌────────────────────────────────────────────────────┐  │
│  │           IGlobalFilterProvider 体系                │  │
│  │  ┌─────────────────────┐  ┌──────────────────────┐ │  │
│  │  │ DefaultGlobal       │  │ DataPermission       │ │  │
│  │  │ FilterProvider      │  │ FilterProvider       │ │  │
│  │  │ (软删除/多租户/多应用)│  │ (数据权限桥接)       │ │  │
│  │  └─────────────────────┘  └──────────┬───────────┘ │  │
│  └───────────────────────────────────────┼─────────────┘  │
└──────────────────────────────────────────┼───────────────┘
                                           │
                                           ▼
┌──────────────────────────────────────────────────────────┐
│              IDataPermissionResolver                      │
│              (DataPermissionResolver)                     │
│                                                          │
│  聚合所有 IDataPermissionFilter,按 Order 排序,          │
│  通过 AndAlso 合并为统一过滤表达式                        │
│                                                          │
│  ┌───────────┐ ┌──────────────────┐ ┌─────────────────┐  │
│  │ RoleData  │ │ DeptData         │ │ PersonalData    │  │
│  │ ScopeFilter│ │ PermissionFilter │ │ PermissionFilter│  │
│  │ (Order=5) │ │ (Order=10)       │ │ (Order=20)      │  │
│  └───────────┘ └──────────────────┘ └─────────────────┘  │
└───────────────────────────┬──────────────────────────────┘
                            │
                            ▼
┌──────────────────────────────────────────────────────────┐
│              IDataPermissionContext(Scoped)              │
│  UserId │ UserName │ DeptId │ RoleIds │ DataScope │ DeptIds │
│  由中台实现,通常从 JWT / Session 中解析                   │
└──────────────────────────────────────────────────────────┘

核心类型一览

类型 职责
IDataPermissionContext 当前用户权限上下文(UserId、DeptId、DataScope 等)
IDataPermissionResolver 聚合所有过滤器,生成最终过滤表达式
IDataPermissionFilter 单维度过滤器接口,自定义过滤器的扩展点
DataPermissionOptions 配置项,通过 AddFilter<T>() 注册过滤器
DataPermissionFilterProvider 桥接 IDataPermissionResolver 到 EF Core IGlobalFilterProvider
DataScope 数据范围枚举(All / Dept / DeptAndChild / Personal / Custom)

生命周期

服务 生命周期 说明
IDataPermissionResolver Singleton 无状态,可安全复用
IDataPermissionFilter Transient 每次解析创建新实例,支持多过滤器并行
IDataPermissionContext Scoped 每个请求一份,由业务层注册
IGlobalFilterProvider Singleton 每次查询时通过 IServiceProvider 获取 Scoped 上下文

优雅降级

  • IDataPermissionContext 未注册或解析为 null 时(如后台服务、迁移场景),所有过滤器自动跳过,不添加任何限制
  • 实体未实现对应标记接口时,该维度的过滤器自动跳过
  • 框架不抛异常,确保非 Web 场景正常运行
Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
26.7.25.1 0 7/25/2026
26.7.24.2 32 7/24/2026
26.7.24.1 35 7/24/2026
26.7.22.1 50 7/23/2026
26.7.21.1 85 7/21/2026
26.7.20.2 83 7/20/2026
26.7.20.1 81 7/20/2026
26.7.19.3 83 7/19/2026
26.7.19.2 84 7/19/2026
26.7.19.1 80 7/19/2026
26.7.18.2 85 7/18/2026
26.7.18.1 79 7/18/2026
26.7.17.1 85 7/17/2026
26.7.14.1 89 7/14/2026
26.7.13.1 88 7/13/2026
26.7.12.1 92 7/12/2026
26.7.11.1 89 7/11/2026
26.7.10.2 94 7/10/2026
26.7.10.1 92 7/10/2026
26.7.7.2 109 7/7/2026
Loading failed