如何使用ASP.NET Core从DbContext中的JWT获取用户名?

Mor*_*siu 1 c# claims-based-identity jwt .net-core asp.net-core

MyDbContext中,我有LogChanges方法,该方法使用以下信息记录我的日志表中的所有更改:

TableName = entityName,
IDRow = JsonConvert.SerializeObject(primaryKeys),
Value = JsonConvert.SerializeObject(values),
Date = dateTimeNow,
Author = userFromJWT
Run Code Online (Sandbox Code Playgroud)

我想将Author设置为JWT授权的User。从这部分完全是:

“ sub”:“ myUserName”

如何在MyDbContext中获取该用户名?也许某种去掺杂剂注射?

提前致谢!

@解

启动文件

   public void ConfigureServices(IServiceCollection services) {
       // ...
       services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
           .AddJwtBearer(options => {
          options.TokenValidationParameters = new TokenValidationParameters {
            ValidateIssuer = true,
            ValidateAudience = true,
            ValidateLifetime = true,
            ValidateIssuerSigningKey = true,
            ValidIssuer = Configuration["Jwt:Issuer"],
            ValidAudience = Configuration["Jwt:Issuer"],
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:Key"]))
          };
        });
      services.AddHttpContextAccessor();
      //...
    }
Run Code Online (Sandbox Code Playgroud)

MyDbContext.cs

// ...
private readonly IHttpContextAccessor _httpContext;

public MyDbContext(DbContextOptions options, IHttpContextAccessor httpContext) : base(options) {
  _httpContext = httpContext;
}
//..
Run Code Online (Sandbox Code Playgroud)

并从我使用的JWT的声明中(从“ sub”中)获得名称

_httpContext.HttpContext.User.Claims.SingleOrDefault(
        c => c.Type == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier")?.Value
Run Code Online (Sandbox Code Playgroud)

Chr*_*att 5

假设您实际上已经集成到ASP.NET Core身份验证子系统(即services.AddAuthenticationapp.UseAuthentication)中,那么这实际上是为您处理的。将读取JWT以从中构建一个ClaimsPrincipal实例,然后将其存储在中HttpContext.User。因此,用户的用户名将位于的标准位置HttpContext.User.Identity.Name,或者您可以通过上的Claims集合直接访问用户名(以及任何其他声明)HttpContext.User.Identity

如果问题是您在无法直接访问的HttpContext.User地方(基本上是控制器或视图之外的任何地方)需要此信息,则只需注入IHttpContextAccessor。这需要两件事:

  1. 您必须添加IHttpContextAccessor服务。出于性能原因,默认情况下不包含它。(这并不是说它会对性能产生严重影响。简单来说,如果您不需要它,则可以通过不包含它来获得更多性能。ASP.NETCore就是只包含您所需要的内容。需要包括。)无论如何:

    ASP.NET Core 2.1

    services.AddHttpContextAccessor();
    
    Run Code Online (Sandbox Code Playgroud)

    之前的版本

    services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
    
    Run Code Online (Sandbox Code Playgroud)
  2. 无论您在何处注入,它都必须是请求管道的一部分,否则HttpContext将不存在。这不应该成为问题,因为无论如何,您都依赖于JWT的存在。请记住,您不能在常规控制台应用程序等中使用此功能。