在令牌中配置组声明和应用角色

在令牌中配置组声明和应用角色演示了如何使用应用角色定义配置应用,并将安全组分配给应用角色,以便提高灵活性和控制,同时使用最低特权提高应用程序安全性。

Microsoft Entra ID 支持将分配给用户的安全组、Microsoft Entra 目录角色和通讯组作为令牌中的声明发送。 可以使用此方法在应用中驱动授权。 但是,Microsoft Entra ID 按令牌的大小限制令牌中的安全组支持。 如果用户是过多组的成员,则令牌中将没有安全组。

在本文中,你将了解使用 Microsoft Entra 安全组支持在令牌中获取用户信息的替代方法。 通过应用角色定义来配置应用,并将安全组分配给应用角色。 这种零信任开发人员最佳做法可提高灵活性和控制性,同时提高应用程序安全性(最低特权)

在应用程序内可用于授权的令牌中,可以配置组声明。 请记住,只有当你收到令牌时,令牌中的组信息才是最新的。 组声明支持两种主要模式:

  • 由组的 Microsoft Entra 对象标识符 (OID) 特性标识的组。
  • 按 Active Directory 同步组和用户的 sAMAccountNameGroupSID 特性标识的组。

组成员身份可以推动授权决策。 例如,下例显示了令牌中的一些声明。 可以将组声明和角色添加到 ID 或访问令牌。

"aud": "e18c04b1-4868-4b93-93d1-8d71f17ab99b", 
"iss": "https://login.microsoftonline.com/833ced3d-cb2e-41de-92f1-29e2af035ddc/v2.0", 
"iat": 1669657224, "nbf": 1669657224, "exp": 1669661124, 
"groups": [ 
   "0760b6cf-170e-4a14-91b3-4b78e0739963", 
   "3b2b0c93-acd8-4208-8eba-7a48db1cd4c0" 
 ],
"oid": "cb7eda1b-d09a-40ae-b8bb-37836ebc6abd",
"sub": "3OBtLXUC2ZrN_ADLNjW9X4o0lcd61py7lgHw3Skh77s",
"tid": "833ced3d-cb2e-41ce-92f1-29e2af035ddc", 
"ver": "2.0", 
"wids": [ 
   "cf1c38e5-3621-4004-a7cb-879624dced7c", 
   "b79fbf4d-3ef9-4689-8143-76b194e85509" 
 ]

groups 声明数组包含此用户所属的组的 ID。 wids 数组包含分配给此用户的 Microsoft Entra 角色的 ID。 此处,cf1c38e5-3621-4004-a7cb-879624dced7c 显示分配给此用户的角色包括应用程序开发人员和标准成员,如 3b2b0c93-acd8-4208-8eba-7a48db1cd4c0 所示。

你的应用可以根据这些声明及其值是否存在做出授权决策。 有关 wids 声明的值的列表,请参阅 Microsoft Entra 内置角色

要将 groupswids 声明添加到令牌,选择“所有组”,如下例的“应用注册” | “令牌配置” | “可选声明” | “编辑组声明”屏幕中所示。

“编辑组声明”屏幕的屏幕截图,其中显示了所选的组类型:分配给应用程序的组。

组超额

请求令牌中的所有组时,如上例中所示,不能依赖令牌中有 groups 声明的令牌。 令牌和 groups 声明存在大小限制,因此它们不会变得太大。 当用户是过多组的成员时,你的应用需要从 Microsoft Graph 获取用户的组成员身份。 groups 声明中的组限制为:

  • JWT 令牌 200 个组。
  • SAML 令牌 150 个组。
  • 使用隐式流时(例如,使用通过混合流的隐式流部分获取 ID 令牌的 ASP.NET 核心),有六个组。
    • 不再建议对单页 Web 应用使用隐式流。
    • 隐式流只能在 OAuth2 混合流中用于 ID 令牌的 Web 应用中,绝不能用于访问令牌。

如果使用 OpenID Connect 或 OAuth2,令牌中最多可以有 200 个组。 如果使用 SAML,则只能有 150 个组,因为 SAML 令牌比 OAuth2 和 OpenID Connect 令牌更大。 如果使用隐式流,则限制为六个组,因为这些响应显示在 URL 中。 在所有这些情况下,不会有 groups 声明,而是出现一个指示(称为组超额),告诉你用户是过多组的成员,无法容纳在令牌中。

在以下令牌示例中,对于 OpenID Connect 或 OAuth2、JSON Web 令牌 (JWT),如果用户是过多组的成员,则不会有 groups 声明。 相反,将有一个包含数组 groups 成员的 _claim_names 声明。

示例令牌的屏幕截图显示了 Azure AD Graph 的查询。

在上面的令牌示例中,可以看到 groups 声明应映射到 src1。 理论上,你随后将查找 _claim_sources 声明,然后找到 src1 成员。 从那里可以找到将用于获取组成员身份的 Graph 查询。 但是,在示例 Graph 查询中看到的内容存在问题。 它转到 Azure AD Graph(Microsoft 即将弃用),因此不要使用它。

隐式流超额指示通过 hasgroups 声明而非 groups 声明完成。

为了确保使用组成员身份进行适当授权,请让应用检查 groups 声明。 如果存在,使用该声明来确定用户的组成员身份。 如果没有 groups 声明,则检查 hasgroups 声明或包含数组 groups 成员的 _claim_names 声明是否存在。 如果存在上述任一声明,则用户是令牌的过多组的成员。 在这种情况下,你的应用必须使用 Microsoft Graph 来确定用户的组成员身份。 请参阅列出用户的成员身份(直接和可传递),以查找用户属于的所有组(作为直接和可传递成员)。

如果应用程序需要实时组成员身份信息,则使用 Microsoft Graph 来确定组成员身份。 请记住,收到的令牌中的信息仅在调用 Microsoft Graph 时是最新的。

请参阅以下示例中的“应用注册” | “令牌配置” | “可选声明” | “编辑组声明”屏幕。 避免点击组超额声明的一种方法是在“编辑组声明”屏幕上选择“分配给应用程序的组”,而不是“所有组”

“编辑组声明”屏幕的屏幕截图,其中显示了所选组类型:安全组、目录角色和所有组。

如果选择“分配给应用程序的组”,则当满足以下条件时,groups 声明中包含一个组:

在本文发布时,“分配给应用程序的组”选项不支持间接成员身份。 组分配至少需要 P1 级许可证。 免费租户无法将组分配给应用程序。

组和应用角色

避免组超额问题的另一种方法是让应用定义允许用户和组作为成员类型的应用角色。 如下例的“应用注册” | “应用角色” | “创建应用角色”屏幕中所示,选择“用户/组”作为“允许的成员类型”

“创建应用角色”屏幕的屏幕截图,其中显示了“允许的成员类型:用户/组”。

在应用注册中创建应用角色后,IT 专业人员可以向该角色分配用户和组。 应用将在令牌(应用 ID 令牌、API 访问令牌)中获取 roles 声明,其中包含所有已登录用户分配到的角色,如以下令牌示例所示。

"aud": "acaf6ce9-81f0-462a-a93d-a314070738d3",
"iss": "https://login.microsoftonline.com/833ced3d-cb2e-41de-92f1-29e2af035ddc/v2.0",
"iat": 1670826509, "nbf": 1670826509, "exp": 1670830409,
"name": "Kyle Marsh",
"oid": "cb7eda1b-d09a-419e-b8bb-37836ebc6abd",
"preferred_username": "kylemar@idfordevs.dev",
"roles": [
 "Approver",
 "Reviewer" 
],
"sub": "dx-4lf-0loB3c3uVrULnZ2VTLuRRWYff0q7-QlIfYU4",
"tid": "833ced3d-cb3e-41de-92f1-29e2af035ddc",

请记住,让应用程序处理以下条件:

  • 缺少 roles 声明
  • 用户尚未分配到任何角色
  • 给用户分配了多个角色时 roles 声明中有多个值

创建允许用户和组作为成员的应用角色时,请始终定义没有提升的授权角色的基线用户角色。 当企业应用配置需要分配时,只有直接分配给应用的用户或分配给应用的组中的成员才能使用该应用。

如果应用定义了允许用户和组作为成员的应用角色,则向应用分配用户或组时,定义的应用角色之一必须是用户或组分配给应用的一部分。 如果应用仅定义了应用的提升角色(例如 admin),则会为所有用户和组分配管理员角色。 定义基本角色(例如 user)时,可以向分配给应用的用户和组分配基本用户角色。

除了避免组超额声明之外,使用角色的另一个优点是不需要在组 ID 或名称及其在应用程序中的含义之间进行映射。 例如,代码可以查找管理员角色声明,而不是循环访问 groups 声明中的组,并决定应允许哪些组 ID 具有管理员功能。

在代码中验证和使用角色

为应用定义应用角色时,你有责任为这些角色实施授权逻辑。 请参阅在应用程序中实现基于角色的访问控制,以了解如何在应用中实现授权逻辑。

后续步骤