客户打电话时如何识别用户?

How to identify user when client makes calls?

我有自定义 cookie 身份验证工作。我想我也可以让服务器端授权工作。我遇到的麻烦是客户端授权。 (即:客户端如何知道什么可以访问或不能访问?)

因此,例如,假设有一项功能仅限于某些用户使用。在我的用户数据中,我可以有一个标志,指示哪些用户可以或不能访问该功能。然后我可以在登录时设置一个角色值,指示可以访问该功能的用户属于特定角色。然后,我可以在处理程序方法上设置授权属性,以表明只有具有该角色的用户才能访问该处理程序。

这可以防止未经授权的用户调用该处理程序(理论上;我尚未对此进行测试,但它似乎应该有效)。但是,在我构建 UI 的客户端,我如何知道是否将该功能添加到 UI 中?

我可以 return 一个 UserInfo 对象到客户端,告诉客户端允许或不允许做什么,然后相应地构建 UI。这样做的问题是它需要在页面刷新之间保存该数据。我必须将它放在本地存储、索引数据库或类似的地方。

我可以有一个 AJAX 处理程序,让客户端询问是否允许它做某事。我认为这似乎是最好的方法,但我必须以某种方式识别用户。同样,我会遇到用户需要记住一些用户信息(至少是用户名或用户 ID)以便向 AJAX 方法标识自己的问题。

似乎这正是身份验证 Cookie 值的用途。事实上,据我所知,它已经随每个请求一起发送了。所以我需要做的就是在登录时在服务器端检索该值,这样我就可以记住哪个 auth cookie 与哪个用户相关联(因此可以或不能访问某些功能),然后在未来 AJAX 次调用,与用户数据库进行比较。

那么接下来的问题是,我如何检索这个值?我认为我可以通过以下方式从未来的请求中检索它:

var authKey = HttpContext.Request.Cookies[MyAuthCookieName];

但是生成的时候怎么第一时间记住呢?显然我无法读取响应 cookie;它们只能被添加或删除。生成 auth cookie 时如何从中获取唯一标识值?它应该是这样的,但它不起作用:

var claims = new List<Claim> {
   new Claim(ClaimTypes.Name, username)
};

if (canAccessFeature)
   claims.Add(
      new Claim(ClaimTypes.Role, "FeatureRole")
   );

var identity = new ClaimsIdentity(
   claims,
   CookieAuthenticationDefaults.AuthenticationScheme
);

var principal = new ClaimsPrincipal(identity);

await HttpContext.SignInAsync(
   CookieAuthenticationDefaults.AuthenticationScheme,
   principal,
   new AuthenticationProperties {
      IsPersistent = true
   }
);

var cookie = HttpContext.Response.Cookies[MyAuthCookieName]; // ERROR: cannot index

好的,我意识到我可以通过 PageModel 上的 User 属性 访问用户信息。您可以使用 IsInRole 方法来测试您是否将用户添加到角色。

无需在客户端保存信息,您可以只使用一个处理程序来告诉您您是否在某个角色中,以便客户端可以知道是否以一种方式或另一种方式构建 UI:

public IActionResult OnGetCanUseFeature() =>
   new JsonResult(
      User.IsInRole("FeatureRole")
   );

为了保护实际的处理程序,请注意 [Authorize] 属性在处理程序级别的 Razor 页面上不起作用。但是你可以简单地询问用户是否在一个角色中,如果没有,可以 return 一个 403 状态结果:

public IActionResult OnPostRestrictedFeature() {
   if (!User.IsInRole("FeatureRole"))
      return new StatusCodeResult(403);

   ...