C# 和 ASP.NET 核心 6:"session" 中的身份验证和用户详细信息

C# and ASP.NET Core 6 : authentication and user details in "session"

我会收到很多 “好的爷爷” 评论。

我已经阅读了十几篇文章和我能找到的关于这个主题的所有 SO 问题。

我一定是离开太久或者完全错过了什么,因为我发誓以前的用户认证非常简单。我似乎记得 built-in 方法和服务器上的 session 只是通过 cookie 或类似的方式知道用户是谁,并且能够“在 session 中”存储信息。我什至不记得过去几年设置身份验证,只是 built-in 到新应用程序。

相反,the most succinct guide I could find 非常复杂。我想我需要一个令牌 authorization/authentication 设置,因为这些天可能有些消费者(如应用程序)没有典型的 cookie 模式。在我看来,令牌就像 cookie 一样工作,只是它是手动保存在用户端并通过 header 随每个请求传递的?

值得称赞的是,该指南有效,至少在登录和正确使用控制器中的简单 Authorize 属性方面是这样。但是,User.Identity.Name 始终为空,即使 User.Identity.IsAuthenticatedtrue,这也令人费解。

我认为 auth 是如何工作的:

所以这是我的问题所在:

我需要更多有关用户的数据,例如每次请求都可以访问整个 UserModel,但我不想每次都去数据库中查找。这是我认为内存中应该只有 session object 的地方,但令牌身份验证似乎并非如此。


TL;DR:

我在哪里放置 user-specific、short-term ("session") 信息,以便在以后的请求中使用,其中用户在授权中使用 JWT 标识 header 而不是 cookie?

The server decrypts this JWT to identify the user This is probably where I'm wrong

JWT 令牌未加密,已签名,因此您无法更改。比如你看jwt.io就可以打开

Where do I put user-specific, short-term ("session") information for consumption in future requests where a user is identified with a JWT in the Authorization header instead of a cookie?

你把它放在令牌的原则声明中。在您链接的指南中写道:

  var claims = new List<Claim>
  {
       new Claim(JwtRegisteredClaimNames.NameId, user.UserName)
  };

因此,您可以将任何您想要的内容添加到声明中以将其存储在令牌上,稍后您可以通过以下方式访问此数据:

var claim = _contextAccessor.HttpContext.User?.Claims.FirstOrDefault(d =>
                    d.Type == ClaimTypes.NameIdentifier);

您也不能使用您列出的任何其他示例,例如 HttpContext.Items,因为它们没有签名。如果令牌以任何方式被更改,系统会识别它并且 returns a 401