繁体   English   中英

ASP.NET Core 声明是否旨在指定用户可以做什么

[英]Is ASP.NET Core claims intended to specify what user can do

ASP.NET Identity 创建了像 UserClaims、UserRoleClaims 这样的表,这正是我所需要的。 我在应用程序中设置了用户可以或不能访问的功能,例如预订页面、图像页面。 目前,所有这些权限都附加到角色,而不是用户,例如,如果我说所有具有 admin 角色的用户都可以访问保留页面,所有具有 admin 角色的用户都可以访问它。

在 UserClaims 中,我将指定多行“访问图像”、“访问预订页面”,在 UserRoleClaims 中,我将指定每个角色具有哪些“声明”。

另一种方法是创建类似的表,如 Permissions 和 RolePermissions,它们在结构上与 ASP.NET Identity 创建的表非常相似。

将我的权限放在声明中似乎有些奇怪,但好在一切都已准备就绪。 ASP.NET Identity UserClaims 应该处理这个权限问题还是它们只是“描述”用户的简单键值对?

声明是一个主体(例如个人或组织)对其自身或另一个主体所做的陈述。 根据我的经验,它不应该是特定的“CanReadReport”、“CanWriteToCustomerDatabase”。 相反,为了获得更大的灵活性,我更喜欢在以下声明时:

InManagement:是/否 InEconomny:是/否 销售:是/否 员工:是/否 顾问:是/否 会计师:是/否

然后由应用程序通过策略来评估谁应该访问什么。

这篇博文可能对您有所帮助: 身份与权限

解决这个问题的一种方法是将资源/动作对存储在声明中并实现一些基础设施(特殊属性等)以在控制器动作上声明性地要求这些声明。

在你的情况下,这些对可能看起来像

资源 行动
图片 使用权
图片 上传
预订页面 使用权

在大多数情况下,实际上将索赔视为群体。 基本上,它是关于用户是什么或可以做什么的声明 - 如果您更习惯于这些术语,那么在逻辑上可以很容易地将其视为组成员资格。 然后,您可以(通过表格)从这些列表中编写特定操作(即权限组具有)的列表,并在控制器中测试这些操作。

是的,所以索赔?! 将声明视为与 ASP.Net Identity 框架实现非常不同的东西,您可以选择在默认项目中获取,其中包括您询问的表。

当然识别框架会生成表来处理这种情况,但最终它并不是它的全部内容,整个声明或令牌事物,这是声明变得有趣的时候 - 它只是它的一个实现,另一个可能是为了实例通常是一个 Json Web 令牌 (JWT),用作带有 REST API 的不记名令牌,无论您在这两种情况下得到什么?

你会得到一堆加密和防篡改的数据,因为它已经从你自己的服务器上获得了内容证明,并且你有一个 (key, valuebag) 类型的数据,如果你只是曾经提供过一个。

然后是 asp.net 支持策略,它基本上使您能够说该策略要求所述数据块包含以下内容,然后……然后可以将其用于方法和控制器。

也可以通过编程方式轻松访问这些声明,因此当请求从经过身份验证的用户传入 api 时,任何 api 实例都假定您有许多负载平衡设置,并且请求已经携带诸如用户 ID、某些控制器或 ui 含义_full_name 之类的东西值 ["view", "edit", "add", ... ] 例如

带有声明的不记名令牌确实是一种您可以避免对每个请求进行身份验证和授权的方法,并且如果您愿意,您都可以立即使令牌过期并让它们持续多久,这对于网络应用程序非常有用,如果您选择JWT 版本,因为在所有 Web MVVM 框架(如 Angular、React、.. 等)中,在 ui 中访问相同的访问是非常直接的 令牌解密成 Json 在 javascript 中几乎是原始的 JavaScriptObjectNotation 一等公民对象......非常容易使用与任何不是的东西相反。 现在任何编程语言都会反序列化 json,因此您可以快速填充模型。

所以索赔解决了几个问题:

  1. 对后端的请求进行身份验证和授权
  2. 向 ui 提供权限集(如果像这样使用)和功能/部件的激活停用
  3. 发布获取登录/令牌生成流程之外的任何内容的资格
  4. 撤销权限的简单方法

那么你可以提出什么索赔? 随便! 您可以将对象序列化为一个值,只要您使用 base 64 编码或类似编码,如果您愿意,但大多数情况下您不应该这样做。 为什么你想要支持 JavaScript 对象的对象部分,Json 中的 JSO,因为它是我们所拥有的是,每个声明本质上都是一个成员属性,它可以是单个值或数组,并且总是只有字符串才能确保层之间的最大合规性。 显然,您可以将任何内容放入字符串中并在读取和读取时相应地对其进行处理,但为了提高效率,重要的收获是它是一个扁平结构而不是嵌套层次结构(键,值)的列表,其中值有点特殊,具体取决于如果有 0、1 或 seral 值

我敢打赌它会在你身上成长,为了方便你可以从包含的数据库中提供这样的内容,如果你在 VS 的新项目指南中搭建一些东西并免费获得很多处理,那么你为什么不应该,除了必须处理许多不是自己编写的代码之外 - 通常采用这种简单的方法,然后这意味着您将为下一个可以以相同方式构建的作业做准备:)

声明是用户身份的一部分。 它描述了用户什么,而不是它可以做什么。

声明提供比角色更多的粒度和灵活性。 考虑一个示例,其中只有 18 岁以上的人才能访问您的应用程序中的某个功能。 您可能为此有一个角色,但这很笨拙,因为您需要确保用户在成年后被添加到这个角色中。

使用基于声明的授权,用户将拥有声明DateOfBirth ,当用户尝试访问年龄限制内容时,您将根据该声明执行安全检查。

identity.AddClaim(new Claim("DateOfBirth", user.DateOfBirth));

进行声明检查的一个好方法是使用策略(也可以与角色一起使用):

services.AddAuthorization(options =>
{
    options.AddPolicy("MustBe18", policy => 
    {
        policy.Requirements.Add(new MinimumAgeRequirement(18));
    });
    options.AddPolicy("MustBeAdmin", policy => policy.RequireRole("Admin");
});

您可以将这些策略应用于具有以下属性的控制器:

[Authorize(Policy = "MustBe18")]
public class AdultController : Controller
{
    // Age restricted content
}

[Authorize(Policy = "MustBeAdmin")]
public class AdminController : Controller
{
    // Administration panel
}

ASP.NET Identity 为您提供了通过 UserClaims 表扩展您的用户的方法。

值得注意的是,至少根据我读过的一些关于该主题的 博客SO 帖子,角色被认为是遗留功能,主要是为了向后兼容。 我还没有找到这种说法的来源,而且在某些情况下,角色对我来说似乎仍然有用,因此请从中获取您想要的内容。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM