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

如何在Audit.EntityFrameworkCore中获取HttpContext Identity用户名

解决Audit.EntityFrameworkCore获取HttpContext用户而非Windows用户的问题

核心原因

eventItem.Environment.UserName 默认读取的是系统进程的Windows用户,而非ASP.NET Core请求上下文(HttpContext)中的当前登录用户。

解决方案

方法1:全局注入HttpContext用户信息

在ASP.NET Core中,通过IHttpContextAccessor获取当前请求的用户,并全局配置到审计事件中:

  1. 确保DI容器已注册IHttpContextAccessor(ASP.NET Core 3.0+默认已注册,若未注册需手动添加):
builder.Services.AddHttpContextAccessor();
  1. 修改审计配置,替换默认用户来源:
var httpContextAccessor = app.Services.GetRequiredService<IHttpContextAccessor>();

Audit.Core.Configuration.Setup()
    .UseEntityFramework(ef => ef
        .UseDbContext<MyDbContext>(auditDbContextOptions)
        .AuditTypeMapper(t => typeof(DbChange))
        .AuditEntityAction<DbChange>((eventItem, entry, entity) =>
        {
            // 从HttpContext获取当前登录用户
            var currentUser = httpContextAccessor.HttpContext?.User?.Identity?.Name;
            
            entity.TablePK = entry.PrimaryKey.Count == 1
                ? entry.PrimaryKey.ElementAt(0).Value.ToString()
                : JsonConvert.SerializeObject(entry.PrimaryKey);
            entity.TableName = entry.Table;
            entity.AuditAction = entry.Action;
            entity.AuditDate = DateTimeOffset.UtcNow;
            entity.AuditData = JsonConvert.SerializeObject(entry);
            // 优先使用HttpContext用户,为空则回退到系统用户
            entity.AuditUser = currentUser ?? eventItem.Environment.UserName;
            entity.RequestId = eventItem.GetEntityFrameworkEvent().ContextId;
        }).IgnoreMatchedProperties())
    // 可选:全局统一设置审计事件的UserName
    .WithCustomAction(scope =>
    {
        var currentUser = httpContextAccessor.HttpContext?.User?.Identity?.Name;
        if (!string.IsNullOrEmpty(currentUser))
        {
            scope.Event.Environment.UserName = currentUser;
        }
    });

方法2:手动创建AuditScope时指定用户

若审计操作是手动触发的,可在创建AuditScope时直接传入当前用户:

var currentUser = httpContextAccessor.HttpContext?.User?.Identity?.Name;

using (var scope = AuditScope.Create("EF Audit", () => new { }, new AuditScopeOptions
{
    Environment = new AuditEnvironmentInfo
    {
        UserName = currentUser ?? Environment.UserName
    }
}))
{
    _dbContext.SaveChanges();
}

方法3:利用Audit.AspNetCore扩展自动捕获用户

若项目引用Audit.AspNetCore包,可直接启用ASP.NET Core集成,自动将当前用户填充到审计事件:

builder.Services.AddAuditNet(config =>
{
    config.Setup()
        .UseEntityFramework(ef => ef
            .UseDbContext<MyDbContext>(auditDbContextOptions)
            .AuditTypeMapper(t => typeof(DbChange))
            .AuditEntityAction<DbChange>((eventItem, entry, entity) =>
            {
                // 此时eventItem.Environment.UserName已自动填充为HttpContext中的用户
                entity.AuditUser = eventItem.Environment.UserName;
                // 其他字段赋值逻辑...
            }).IgnoreMatchedProperties());
    
    // 启用ASP.NET Core集成,自动捕获HttpContext信息
    config.WithAspNetCore(a => a
        .IncludeUser(true)); // 自动将当前登录用户设置到审计事件的UserName中
});

注意事项

  • 若在后台任务中执行EF操作,HttpContext会为null,此时需手动传入任务执行的用户,或回退到系统用户。
  • 使用Identity框架时,可通过httpContextAccessor.HttpContext?.User.FindFirst(ClaimTypes.NameIdentifier)?.Value获取用户ID,替代用户名。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 09:35:22