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

本文可帮助你使用应用角色定义配置应用,并将安全组分配到应用角色,以便你可以提高灵活性和控制,同时提高应用程序安全性(最低特权)。

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

本文介绍了使用 Microsoft Entra 组支持在令牌中获取用户信息的替代方法。 相反,您使用应用角色定义配置您的应用,并将组分配给应用角色。 此 零信任 开发人员最佳做法可提高灵活性和控制力,同时 以最低特权提高应用程序安全性。

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

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

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

"aud": "00001111-aaaa-2222-bbbb-3333cccc4444", 
"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": "aaaaaaaa-0000-1111-2222-bbbbbbbbbbbb",
"sub": "3OBtLXUC2ZrN_ADLNjW9X4o0lcd61py7lgHw3Skh77s",
"tid": "bbbbcccc-1111-dddd-2222-eeee3333ffff", 
"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 声明中的组限制为:

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

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

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

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

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

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

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

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

选择分配给应用程序的 组时,如果满足以下条件,则 索赔中包含该组:

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

组和应用角色

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

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

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

"aud": "11112222-bbbb-3333-cccc-4444dddd5555",
"iss": "https://login.microsoftonline.com/833ced3d-cb2e-41de-92f1-29e2af035ddc/v2.0",
"iat": 1670826509, "nbf": 1670826509, "exp": 1670830409,
"name": "Kyle Marsh",
"oid": "bbbbbbbb-1111-2222-3333-cccccccccccc",
"preferred_username": "kylemar@idfordevs.dev",
"roles": [
 "Approver",
 "Reviewer" 
],
"sub": "dx-4lf-0loB3c3uVrULnZ2VTLuRRWYff0q7-QlIfYU4",
"tid": "ccccdddd-2222-eeee-3333-ffff4444aaaa",

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

  • 缺少 roles 声明
  • 用户没有角色分配
  • 在用户拥有多于一个角色分配时,roles 声明中存在多个值。

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

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

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

验证和使用代码中的角色

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

后续步骤