XiHan Framework 处于预览阶段

查看获取方式
跳转到内容

XiHan.Framework.Auditing.Abstractions ​

审计的抽象包:Observe 阶段的审计中间件、调用上下文上补充动作 / 资源 / 细节的扩展、查询契约 IAuditTrail 与选项。能力 auditing.trail@1 由引用它的 Provider 提供。

项内容
包 IDXiHan.Framework.Auditing.Abstractions
环层Ring 2(抽象)
能力定义 auditing.trail@1(AuditingCapabilities.Trail),本包不提供;Provider 是 Auditing.InMemory、Auditing.Database
特性入口—(Provider 在装配时调用 AddAuditing())
配置节XiHan:Auditing
依赖XiHan.Framework.Kernel、XiHan.Framework.Localization.Abstractions;Microsoft.Extensions.Configuration.Abstractions
AOT兼容
稳定性Preview(AuditEvent、IAuditSink 在内核,Stable)

概述 ​

内核定义审计事件 AuditEvent 与接收器 IAuditSink,默认的 NullAuditSink 丢弃全部事件。本包补上产生事件与读回事件的部分:

  • AuditMiddleware 挂在 Observe 阶段末尾,调用结束后按显式动作或 AuditSelection 决定是否记录;结果优先取管道写入的 outcome,主体与租户先取安全上下文、再回退 Baggage(ADR-0036);接收器故障只记日志。
  • AuditInvocationExtensions 让处理器在调用期间写入动作、资源名与细节。
  • IAuditTrail 按时间、动作、主体、租户、trace-id、成败过滤,按写入顺序升序分页。

本包不存储任何东西,存储由 Provider 实现。用法与行为细节见审计。

何时使用 ​

应用代码只引用本包的扩展与查询契约,装配时再选存储 Provider:开发与单实例用 Auditing.InMemory,要持久化与按租户、主体、时间查询时用 Auditing.Database。自写 Provider 时实现 IAuditSink 与 IAuditTrail,被选中后调用 AddAuditing(),并通过 Auditing.Conformance 的 AuditTrailConformance。

安装与启用 ​

bash
dotnet add package XiHan.Framework.Auditing.Abstractions --prerelease

当前是预览版,安装要带 --prerelease;从源码或本地包源引用见快速上手。两个 Provider 都依赖本包,装配 Provider 即可;Profiles.Full 已包含 Auditing.InMemory。

配置 ​

键类型缺省说明
XiHan:Auditing:SelectionProtected / All / None(不区分大小写)Protected没有显式动作时记哪些操作
XiHan:Auditing:IncludeSuccessesbooltrue为 false 时只记失败
XiHan:Auditing:Exclude字符串列表:操作 ID,或以 * 结尾的前缀(profile.*、my-*)空按选择规则挑出的操作命中即不记;显式动作照记;必须写成列表
json
{ "XiHan": { "Auditing": { "Selection": "All", "IncludeSuccesses": false, "Exclude": [ "permissions.current", "profile.*" ] } } }

值不合法时 AuditingOptions.FromConfiguration 抛出 ArgumentException,应用在装配阶段失败;Exclude 写成单个值、某一项是空白、单独的 *、* 不在末尾或含大写与其他字符,同样失败,消息指出配置键与那一项(ADR-0080)。

主要类型 ​

类型说明
AuditingCapabilities能力 ID auditing.trail 与接口版本 1
AuditingOptionsSelection、IncludeSuccesses、Exclude(init 时同样校验每一项);ConfigurationSection 为 XiHan:Auditing
AuditSelectionProtected(只记需要授权的操作:契约声明了 Permission 或 Policy)、All、None(只记显式动作)
Pipeline.AuditMiddlewareObserve 阶段末尾的审计中间件
Pipeline.AuditInvocationExtensionsSetAuditAction、SetAuditResource、AddAuditDetail,以及对应的 GetAuditAction、GetAuditResource、GetAuditDetails
Trail.IAuditTrailQueryAsync(AuditQuery, CancellationToken) → Result<AuditPage>
Trail.AuditQuery过滤项 From、To、Action、PrincipalId、TenantId、TraceId、Succeeded,分页 PageSize、ContinuationToken;Validate()、Matches(AuditEvent)
Trail.AuditPageEvents(按写入顺序升序)与 ContinuationToken(没有下一页为 null)
AuditingFeatureContextExtensionsAddAuditing(this FeatureContext):注册消息目录 auditing 与选项,把中间件挂到 Observe 末尾
AuditingErrors、AuditingMessages错误码与消息键

使用示例 ​

在处理器里补充信息:

csharp
using XiHan.Framework.Auditing.Abstractions.Pipeline;
using XiHan.Framework.Kernel.Operations;
using XiHan.Framework.Kernel.Security;
using XiHan.Framework.Primitives;

namespace MyApp.Orders;

public sealed record CancelOrderRequest(string Id, string Reason);

public sealed record CancelOrderResponse(string Id);

[Operation("orders.cancel", Expose = Expose.Http, Permission = "orders.write")]
public sealed class CancelOrder : IOperation<CancelOrderRequest, CancelOrderResponse>
{
    public ValueTask<Result<CancelOrderResponse>> HandleAsync(CancelOrderRequest request, InvocationContext context)
    {
        // 动作取操作 ID(orders.cancel),这里只补资源与原因
        context.SetAuditResource(new ResourceName("global", "orders", context.GetSecurity().Tenant?.Id ?? string.Empty, "order", request.Id));
        context.AddAuditDetail("reason", request.Reason);
        return ValueTask.FromResult(Result.Success(new CancelOrderResponse(request.Id)));
    }
}

自写存储 Provider 的装配步骤,与 InMemoryAuditingFeature 相同:

  1. 清单声明 Provides = [new CapabilityDeclaration(AuditingCapabilities.Trail, AuditingCapabilities.Version)],Role = ManifestRole.Provider,写法见能力包与清单。
  2. Configure 里把存储登记为单例;context.Node.IsSelectedFor(AuditingCapabilities.Trail) 为真时,用 TryAddSingleton 把同一个实例登记为 IAuditSink 与 IAuditTrail。特性先于内核的默认注册配置,所以 TryAdd 能先于 NullAuditSink 占住接收器。
  3. 同一分支里调用 context.AddAuditing(),注册消息目录与选项并挂上中间件;没被选中时不要调用,否则中间件会挂两次。
  4. WriteAsync 必须有界、不阻塞调用路径;QueryAsync 先调用 query.Validate(),续页令牌不可识别时返回 AUDITING_VALIDATION_001。
  5. 测试项目继承 Auditing.Conformance 的 AuditTrailConformance 并通过全部用例。

行为与限制 ​

  • 记录条件:有显式动作的调用总是记录;没有时只看操作调用并按 Selection 判定,再去掉 Exclude 命中的操作,非操作调用不记录。IncludeSuccesses 为假时成功的调用不记录。
  • 结果:管道写入的 outcome 优先;没写入而抛出了异常时,取消记 KERNEL_CANCELLED_001,其他异常记 KERNEL_UNEXPECTED_001,异常照常向外抛;正常返回却没写结果视为成功。
  • 接收器的写入不带调用的取消令牌,被取消的调用同样记录;接收器抛出的异常以 Error 级记一条日志,不影响调用结果。
  • 细节只允许 JSON 可表示的值,同名覆盖;资源名以 xrn: 文本保存。
  • 事件不带调用来源 InvocationOrigin,需要时由应用写进细节,见审计。
  • 查询页大小 1 到 1000,缺省 100;续页令牌由实现自行校验。
错误码消息键含义
AUDITING_VALIDATION_001auditing.query.invalid查询不合法:页大小越界、起止颠倒或续页令牌不可识别
AUDITING_UNAVAILABLE_001auditing.trail.unavailable审计存储不可达

相关 ​

Released under The MIT License