为啥使用 JWT 时 UserManager.GetUserAsync 返回 null?

Posted

技术标签:

【中文标题】为啥使用 JWT 时 UserManager.GetUserAsync 返回 null?【英文标题】:Why does UserManager.GetUserAsync return null when using JWT?为什么使用 JWT 时 UserManager.GetUserAsync 返回 null? 【发布时间】:2019-01-27 00:20:37 【问题描述】:

我的 .NET CORE 2.1 Web api 存在一些问题。我使用身份框架和 JWT 令牌进行身份验证,但每当我尝试在控制器中获取当前用户时,我都会收到空引用错误。

据我所见,所有设置看起来都很好,我尝试手动设置 Identity 的密钥,但仍然出现相同的错误。有什么想法吗?

控制器:

        var user = await _userManager.GetUserAsync(User);

Startup.cs:

    public void ConfigureServices(IServiceCollection services)
    
      services.AddIdentity<LoginUser, IdentityRole>(options => 
            options.ClaimsIdentity.UserIdClaimType = 
            ClaimTypes.NameIdentifier;
            )
            .AddEntityFrameworkStores<ApplicationDbContext>()
            .AddDefaultTokenProviders();
    

令牌生成声明:

        var claims = new List<Claim>
        
            new Claim(JwtRegisteredClaimNames.Sub, user.Id),
            new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()),
            new Claim(JwtRegisteredClaimNames.Email, email),
            new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())
        ;

【问题讨论】:

【参考方案1】:

无法真正解释为什么会发生这种情况,我想这是因为用户没有真正登录,因为 JWT 是无状态的。

但是,由于以下 sn-p,我设法获得了当前用户:

private async Task<AppUser> GetUser()
        => await _userManager.FindByIdAsync(User.Claims.FirstOrDefault(c => string.Equals(c.Type, Constants.Strings.JwtClaimIdentifiers.Id, StringComparison.InvariantCultureIgnoreCase))?.Value);

【讨论】:

当我尝试在 System.Private.CoreLib 中查找资源时遇到异常:无限递归。这可能是 System.Private.CoreLib 中的错误,也可能是某些可扩展点中的错误,例如程序集解析事件或 CultureInfo 名称。资源名称:Arg_NullReferenceException 您是否将Constants.Strings.JwtClaimIdentifiers.Id 替换为JwtRegisteredClaimNames.Sub

以上是关于为啥使用 JWT 时 UserManager.GetUserAsync 返回 null?的主要内容,如果未能解决你的问题,请参考以下文章

为啥在页面转换时不调用 next-auth jwt 回调?

为啥我的 API 在使用 JWT 后不再工作?

当我们有客户端会话时,为啥我们需要 JWT?

为啥我在 Asp.Net CORE 中使用 JWT 获得 401 未经授权?

为啥 Keycloak 使用 Session-Cookie 而不是 JWT Authorization Header

为啥不将 JWT 访问令牌存储在内存中并在 cookie 中刷新令牌?