BitzOrcas 通过8 级租户解析链实现多租户,配合统一的 ITenantContext 和通过 SqlSugar 全局过滤器的自动数据隔离。
解析链
优先级 1: SystemJob → JobHost 租户上下文 (ICurrentUserAccessor.BeginScope)优先级 2: RootOverride → 超级管理员覆盖(绕过租户)优先级 3: ApplicationCaller → HMAC/API Key client_id → TenantId优先级 4: UserClaim → JWT claim "tenant_id"优先级 5: HostSubdomain → *.tenant.example.com 子域名优先级 6: Header → X-Tenant-Id 头优先级 7: Path → /api/tenants/{tenantId}/... 路径段优先级 8: SingleTenantDefault → 单租户模式回退每个步骤实现 ITenantResolutionStep:
public interface ITenantResolutionStep{ int Order { get; } Task<TenantResolution?> ResolveAsync(TenantResolutionRequest request, CancellationToken ct = default);}租户状态守卫
TenantStatusGuard 执行租户生命周期——未激活/过期租户将被阻止:
public class TenantStatusGuard : ITenantGuard{ public Task<TenantGuardResult> CheckAsync(TenantId tenantId, CancellationToken ct = default);}| 状态 | 行为 |
|---|---|
| Active | 所有操作允许 |
| Suspended | 只读,变更操作被阻止 |
| Expired | 所有操作被阻止 |
| Not Found | 404 响应 |
PlatformTenant 实体
public class PlatformTenantEntity : EntityBase{ public string Name { get; set; } public string? Domain { get; set; } public TenantStatus Status { get; set; } public string? Configuration { get; set; } // JSON 配置}数据隔离
SqlSugar 全局过滤器执行自动租户隔离:
// 自动应用于所有 TenantEntityBase 查询db.QueryFilter.AddTableFilter<TenantEntityBase>( e => e.TenantId == currentTenantId);跨租户查询
对于管理员/超级用户的跨租户操作:
// 使用显式查询绕过租户过滤器var allTenants = await db.Queryable<NoteEntity>() .IgnoreFilter() // 绕过全局过滤器 .ToListAsync();租户上下文
public interface ITenantContext{ TenantId? CurrentTenantId { get; } bool IsResolved { get; } bool IsRootOverride { get; }}- 每个请求作用域(API)或每个任务执行作用域(JobHost)
SystemJobTenantContext单例为后台任务提供租户身份ICurrentUserAccessor.BeginScope()支持运行身份份范围
配置
{ "Tenancy": { "Mode": "MultiTenant", // 或 "SingleTenant" "DefaultTenantId": "0" }}另见
- 多租户深入分析 — 综合架构指南
- Mediator 管道图 — 展示管道中的 TenantGuard