ASP .NET Identity 中的声明是啥

Posted

技术标签:

【中文标题】ASP .NET Identity 中的声明是啥【英文标题】:What is the claims in ASP .NET IdentityASP .NET Identity 中的声明是什么 【发布时间】:2014-03-05 21:39:15 【问题描述】:

有人可以解释一下,新的 ASP.NET Identity Core 中的声明机制是什么意思吗?

如我所见,有一个AspNetUserLogins 表,其中包含UserIdLoginProviderProviderKey

但是,我仍然无法理解或找到关于何时将数据添加到AspNetUserClaims 表以及该表用于什么情况的任何信息?

【问题讨论】:

【参考方案1】:

声明机制在新的 ASP.NET Identity Core 中意味着什么?

有两种基于角色和声明的常见授权方法。

基于角色的安全性

用户被分配到一个或多个角色,用户通过这些角色获得访问权限。 此外,通过将用户分配给角色,用户会立即获得为该角色定义的所有访问权限。

基于声明的安全性

基于声明的身份是一组声明。声明是实体(用户或其他应用程序)做出的关于 本身,这只是一个索赔。例如,声明列表可以包含用户的姓名、用户的电子邮件、用户的年龄、用户对某项操作的授权。 在基于角色的安全性中,用户直接向应用程序提供凭据。在基于索赔的 模型中,用户向应用程序提供声明而不是凭据。声称具有实用性 值,它必须来自应用程序信任的实体。

以下步骤说明了在基于声明的安全模型中发生的顺序:

    用户请求操作。依赖方 (RP) 应用程序询问 代币。 用户将凭据提交给 RP 应用程序信任的颁发机构。 颁发机构在验证用户的身份后颁发带有声明的签名令牌 凭据。 用户将令牌提交给 RP 应用程序。应用程序验证令牌 签名,提取声明,并根据声明,接受或拒绝 请求。

但是,我仍然无法理解和找到任何信息,当数据 添加到 AspNetUserClaims 以及此表用于什么情况?

当您处于未使用基于角色的安全性的情况下,并且您选择使用基于声明的安全性时 安全性,您需要使用 AspNetUserClaims 表。 有关如何在 ASP.NET 标识中使用声明,请参阅下面的链接了解更多信息。

http://kevin-junghans.blogspot.com/2013/12/using-claims-in-aspnet-identity.html

更新

什么时候必须使用基于角色的安全性以及何时使用基于声明的安全性? 你能写几个例子吗?

没有一个非常明确的情况,您会或不会使用基于角色或基于声明的安全性,不像您会使用 A 而不是 B。

但是,基于声明的访问控制允许将授权规则与核心业务逻辑更好地分离。当授权规则发生变化时,核心业务逻辑不受影响。在某些情况下,您可能更喜欢使用基于声明的方法。

有时不需要声明。这是一个重要的免责声明。 拥有大量内部应用程序的公司可以使用 Integrated 实现 Windows 身份验证提供的许多好处 索赔。 Active Directory 在存储用户身份方面做得很好, 由于 Kerberos 是 Windows 的一部分,因此您的应用程序不会 必须包含很多身份验证逻辑。只要每 您构建的应用程序可以使用集成 Windows 身份验证,您 可能已经达到了你的身份乌托邦。然而,有很多 您可能需要 Windows 以外的其他东西的原因 验证。您可能使用了面向 Web 的应用程序 由在您的 Windows 域中没有帐户的人提供。其他 原因可能是您的公司已与另一家公司合并,并且 您在跨两个 Windows 林进行身份验证时遇到问题 不要(也可能永远不会)有信任关系。也许你想 与具有非 .NET Framework 的另一家公司共享身份 应用程序,或者您需要在应用程序之间共享身份 在不同平台上运行(例如,Macintosh)。这些是 仅在少数情况下,基于声明的身份可能是正确的 为您选择。

欲了解更多信息,请访问http://msdn.microsoft.com/en-us/library/ff359101.aspx

【讨论】:

感谢您的回答,但我还是不明白,我什么时候必须使用基于角色的安全性以及何时使用基于声明的安全性?你能写几个例子吗? @FSou1,您不会使用基于角色或基于声明的方法。请参阅我的更新答案以获得更清晰的信息。 对于任何寻找现实生活例子的人,这里是使用驾驶执照和出生日期的好例子。 docs.microsoft.com/en-us/aspnet/core/security/authorization/… 上面文档中简单的两行就解决了很多疑惑。 A Guide to Claims-Based Identity and Access Control 全面解释了基于声明与基于角色的访问控制 (RBAC) 的方法。整本书可通过 MS 下载免费在线获取。 goodreads.com/book/show/… @ChrisMylonas 提到的 RBAC 免费 Microsoft 书籍可以在此处从 Microsoft 免费下载:microsoft.com/en-us/download/details.aspx?id=28362【参考方案2】:

只是为了补充@Lin 上面所说的内容。我具体指的是这个问题:

什么时候必须使用基于角色的安全性以及何时使用基于声明的安全性? 你能写几个例子吗?

我不得不在这个答案中添加更多信息,这是因为我没有明确解决基于声明和基于角色的身份验证模型之间的区别。根据经验和概念本身的性质以及 Microsoft Docs 上的介绍和记录,这两种授权模型经常一起使用,下面的示例 3 说明了它们何时经常一起使用的示例。现在让我们详细讨论一下主题:

基于声明的授权:

需要注意的重要一点是,与基于角色的授权相比,基于声明的授权本质上是受第三方约束的。声明是描述用户的第三方应用程序向您(您的应用程序)提供的信息。该信息可以是任何类型的数据。举个例子吧:

示例 1:

假设您有一个用于混合歌曲的软件应用程序。这个应用程序基本上使用来自 Spotify 或 YouTube 音乐平台等的歌曲,但它的构建方式是它可以完全访问这些平台的音乐库。但是这个应用程序不需要您使用您的 Spotify 或 google 帐户登录,您基本上只需使用电子邮件和密码进行注册。但在您在线后,要使用来自 Spotify 或 Youtube 音乐的音乐,您需要输入用于创建 sportify 或 YouTube 音乐帐户的电子邮件地址。然后应用程序(通过网络服务)从相应的第三方应用程序请求您的订阅帐号并将其存储为声明。因此,每次您在线时尝试访问音乐时,该应用程序都会使用已注册声明的政策来检查您是否有订阅帐户,然后允许访问。这样做的好处是,索赔与信息一起存储,例如您存储索赔来源的发行人。就是这样。您使用了由第三方提供的声明 subscriotionAccountNumber,该声明描述了您站在他们这边。显然,这不是开发此类应用程序的最佳模型,但作为示例已经足够了。您正在根据从另一个第三方应用程序声明的有关用户的一些信息来授权您的用户。

基于角色的授权:

这里的这个已经很清楚了。最简单的方法是,您仅根据用户的角色和角色向用户授予访问权限。

示例 2:

想象一个有来自不同职位的多个用户的组织应用。您可以根据用户的职位为其分配角色,并根据他们的角色授予对不同信息的访问权限。经理、所有者、员工……基本上,并非所有员工都可以访问经理和所有者可以访问的所有内容。这适用于经理和所有者。经理无权访问某些仅属于所有者的信息。就这么简单。

把它们放在一起:

在 ERP 系统等应用程序中,声明和角色一起使用以构建复杂的授权模型。我总是会说当前的身份框架是如此完整,以至于您通常不需要破坏现有模型的不必要的扩展,显然需求可能会有所不同,有时打破模型可能是唯一的选择。当角色和声明一起使用时,声明充当权限。这就是模型中有RoleClaimUserClaim 表的原因。那就是允许您将授权扩展到角色本身之外。当声明与角色一起使用时,它们仅提供执行某些操作的访问权限。

示例 3:

假设您有一个时钟系统,其中有一名技术人员和一名经理。在每周结束时,技术人员必须安排带有时钟信息的报告,显示该周工匠的工作时间,这些信息被合并并由工资单使用。此类系统通常必须在提交最终报告之前进行修改或更正,因为您不想多付或少付您的员工。您可以通过创建Manager RoleTechnician Role 为经理和技术员使用Role-Based 方法。但是Manager Role 是能够访问和编辑工匠时钟信息的。另一方面,您可以让Technician Role 没有这些能力来访问该信息。但这是有趣的部分;经理可以提出索赔并允许技术人员访问时钟系统并进行报告。因此,可以仅针对未经编辑的访问提出声明,或者可以在具有访问和编辑功能的情况下进行声明。请记住,只有您的应用程序才能理解您的声明的含义。它们可以命名为任何名称,GrantWriteAccessGrantReadAccess 等,没有什么可以限制您。将声明预定义为权限后,您需要做的就是将该声明与用户相关联。在这种情况下,技术人员会将GrantWriteAccess GrantReadAccess 添加到他们的UserClaim 表中。

这更像是说,默认情况下,作为经理,我可以访问一些我的技术人员无法访问的信息。但我并不总是在办公室附近?我该怎么做才能让他即使我不在身边也能做这项工作?为了解决这个问题,系统可以为管理人员创建声明(权限)的功能,无需访问某些特定信息。我们经常在我们的 ERP 系统中随处看到这些。无法访问某些模块的用户,当他们被提升时,他们被授予对 ERP 系统更多模块的权限,有时保持相同的用户角色,并且只有一些权限被打开。

【讨论】:

在基于角色的方法中,每个角色都有一个或多个权限,并且您的示例中的经理角色可以被授予向其他角色授予权限的权限,以便经理可以授予技术人员某些权限。所有这些都适用于基于角色的安全性,所以我仍然不清楚为什么我们需要基于声明的安全性! 仔细阅读@EricMutta,经理,可以在不改变其角色的情况下授予技术员权限。这就是声明的来源。显然,不同的角色具有不同的权限,但是如果你想在不改变他们各自角色的情况下向一个人授予权限会发生什么?这就是您使用声明的地方,尤其是当某些事情是暂时的时。所以在我的例子中,技术人员的角色没有改变,但他们被授予访问数据的权限,同时保持他们的角色。 对于某些系统,您可以授予多个角色,例如,可以进一步为技术人员分配(管理员)角色并具有访问权限。但那是如果系统只是基于角色的。我发现将权限拆分为声明会更好,因为这样可以使角色非常灵活... @MosiaThabo 很好的解释,但引用 the docs “创建身份时,可能会为其分配一个或多个由受信任方发出的声明。声明是一个名称值对,代表主题是什么,而不是主题能做什么。" @spencer741 这种解释主要适用于声明来自外部资源的情况。例如,假设您通过 OAuth 使用 Facebook 登录,声明会将您描述为主体,而不是您可以做什么。但是当您在应用程序中使用声明时,它们只能是键值对,允许您根据提供的值访问某些资源。【参考方案3】:

这是来自ASP.NET docs的一个非常简单的解释:

创建身份时,可能会为其分配一个或多个由受信任方发布的声明。 声明是一个名称值对,代表主题是什么,而不是主题可以做什么。例如,您可能拥有由当地驾驶执照颁发机构颁发的驾驶执照。您的驾驶执照上有您的出生日期。在这种情况下,索赔名称将为 DateOfBirth,索赔值将是您的出生日期,例如 1970 年 6 月 8 日,颁发者将是驾驶执照颁发机构。最简单的基于声明的授权检查声明的值并允许根据该值访问资源。

然后继续举一个我们几乎所有人都能理解的例子:

例如,如果您想进入夜总会,授权过程可能是: 在授予您访问权限之前,门禁安全员会评估您的出生日期声明的价值以及他们是否信任颁发者(驾驶执照颁发机构)。

所以要回答我什么时候应该使用基于声明的安全性?这个问题,答案是很难让人们担任明确定义的角色。例如,在夜总会场景中,很难将客户分配到角色中,因此您可以根据他们的 ID(例如驾驶执照)确认的年龄来使用基于声明的访问控制。但是,在同一个夜总会场景中,您可以使用基于角色的安全性来控制谁可以访问哪些房间(例如,使用“仅限员工”房间的钥匙卡)。显然您可以根据需要混合使用基于声明和基于角色的安全性

【讨论】:

【参考方案4】:

ASP.Net 身份验证有两种类型。

    基于角色 基于声明

您可以使用其中一种,也可以同时使用两种。当你有非常明确的事情时,使用基于角色。例如,您创建两个角色教师和学生。只有教师可以添加科目。因此,您将教师角色分配给您希望有权添加主题的用户。

基于索赔更灵活。假设您有一个要求,一些学生也可以添加科目。在这种情况下,您必须再创建一个角色,该角色可以是学生并有权添加主题。但是,如果您使用基于声明的方法,那将非常容易。只需创建 addSubject 之类的声明并将其分配给您想要访问以添加主题的任何用户。

【讨论】:

不好的例子 - addSubject 不是声明,而是许可。声明应该说明身份是什么,而不是它能做什么。 @R.V.来吧...声明可以授权一个动作,并且它们经常被用于此目的。这就是身份框架中有RoleClaim 表的原因。只有当他们来自第三方应用程序时,他们才会经常告诉主题是什么。不在同一个应用程序上。大声笑! @R.V.你不能有一个描述用户的表,然后去复制用户的详细信息并将它们粘贴到索赔表中并说他们描述了用户......那么用户表的目的是什么?

以上是关于ASP .NET Identity 中的声明是啥的主要内容,如果未能解决你的问题,请参考以下文章

ASP.NET Core 访问控制器构造函数中的 User.Identity

ASP.NET Identity 3.0 上的 IIdentityMessageService 等价物是啥?

使用 JWT Token-Asp.net Core Identity 通过 Web API 上的角色声明进行授权

使用 ASP.NET Core Identity 3 的用户角色权限

在 ASP.Net Core Identity 中刷新用户 cookie 票证

如何在 ASP.NET Identity 中获取索赔值的最大值?