S8TrustedScopeResolver.cs 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041
  1. using Admin.NET.Core;
  2. namespace Admin.NET.Plugin.AiDOP.Infrastructure;
  3. /// <summary>
  4. /// S8 可信作用域:<b>租户</b>一律由服务端从认证身份解析,
  5. /// 客户端传入的 tenantId / factoryId / body.TenantId / body.FactoryId 不承担任何安全边界作用。
  6. ///
  7. /// <para><b>S8-TENANT-ONLY-BATCH6:Factory 已退出作用域。</b>
  8. /// 原实现要在租户内解析出唯一的「工厂组织」,并在 0 个或多于 1 个时**直接抛异常** ——
  9. /// 于是零工厂 / 多工厂租户连异常列表都打不开,而工厂在 S8 里本就不决定任何数据归属。
  10. /// 该解析连同 <c>Type='501'</c> 工厂组织查询一并删除:S8 不再需要知道"当前是哪个工厂"。</para>
  11. ///
  12. /// <para><b>安全边界没有放松</b>:租户仍只信认证后的 JWT
  13. /// (<see cref="AidopTenantScope.ResolveOrThrow"/>),绝不接受 query 里的 tenantId。
  14. /// 去掉的是一个从不提供隔离、却经常制造故障的维度。</para>
  15. /// </summary>
  16. public sealed record S8TrustedScope(long TenantId)
  17. {
  18. /// <summary>
  19. /// 历史兼容:仍需往 <c>factory_id</c> 列写值的旧代码用它,语义是「租户级、无工厂」。
  20. ///
  21. /// <para>刻意不叫 FactoryId —— 那个名字会让人以为它还是个作用域。
  22. /// 它只是一个写入 legacy 列的占位值,任何查询谓词都不得使用它。</para>
  23. /// </summary>
  24. public long LegacyFactoryId => S8ConfigScope.GlobalFactoryId;
  25. }
  26. /// <summary>
  27. /// S8 租户可信作用域解析器。只解析租户,不再解析工厂。
  28. /// </summary>
  29. public sealed class S8TrustedScopeResolver : ITransient
  30. {
  31. private readonly UserManager _userManager;
  32. public S8TrustedScopeResolver(UserManager userManager) => _userManager = userManager;
  33. /// <summary>解析当前登录身份的 S8 可信作用域;租户无法确定时抛业务异常,绝不回落默认值。</summary>
  34. public Task<S8TrustedScope> ResolveAsync() =>
  35. Task.FromResult(new S8TrustedScope(AidopTenantScope.ResolveOrThrow(_userManager)));
  36. }