令牌保护部署指南 - Web 应用(预览版)

本指南涵盖了部署并强制实施针对登录会话令牌的令牌保护所需的步骤,这些令牌由访问 Azure 资源管理器(ARM)的 Web(基于浏览器的)应用使用。

有关令牌保护和受支持的平台的概述,请参阅 Microsoft Entra 条件访问中的令牌保护。 使用此部署指南之前,请查看概述文档。

注释

Web 应用程序的令牌保护目前为预览版。 预览功能仍在开发中,其功能可能会随时间而变化。 这些功能在正式发布之前可供使用,以便客户可以抢先体验并提供反馈。

注释

由于对 Web 应用程序的支持处于预览状态,因此建议先为本机应用程序部署令牌保护,包括至少为一个试点用户组强制实施策略,然后再尝试此预览版 Web 应用程序。 有关指南,请参阅适用于 WindowsApple 设备的部署指南。

先决条件

使用此功能需要 Microsoft Entra ID P1 许可证。 若要查找适合你的要求的许可证,请参阅 Microsoft Entra ID 的通用可用功能比较

支持的应用程序、资源和浏览器

应用程序

  • Azure 门户
  • Microsoft Intune 管理中心
  • Microsoft Entra 管理中心
  • Microsoft参与中心
  • Microsoft参与中心

仅支持上述 Web 应用程序。 强制实施策略后 ,将阻止用户访问 ARM 的其他 Web 应用程序 。 访问 ARM 但 不支持 的顶级 Web 应用程序包括但不限于:

  • Microsoft 365 安全与合规中心
  • Microsoft AppSource
  • Azure 数据工厂
  • Azure AI Studio 应用
  • Azure Synapse Studio
  • Power BI
  • Microsoft开发人员门户
  • Azure OpenAI Studio
  • Power Platform 管理中心

支持的资源

  • Azure 资源管理器(ARM),在条件访问中配置为 Windows Azure 服务管理 API 资源。

支持的平台和浏览器

平台 支持的浏览器 设备要求
Windows 11(内部版本 26100.8246 / 26200.8246 或更高版本) Microsoft Edge,Google Chrome 已加入 Microsoft Entra、混合加入或已注册1
macOS Microsoft Edge,Google Chrome 仅限 MDM 管理

1 不支持某些设备注册类型。 请参阅 不受支持的设备注册类型列表。

在 Windows 和 macOS 上为 ARM 启用令牌保护

若要最大程度地减少因应用、浏览器或设备不兼容而导致用户中断的可能性,请按照以下建议操作:

  • 从一组试点用户开始,并随着时间推移而扩展。
  • 在强制实施令牌保护之前,在 仅报告模式下 为令牌保护创建条件访问策略。
  • 捕获交互式和非交互式身份验证日志。
  • 分析这些日志的时间足够长,足以涵盖正常的应用程序使用。 以下各节介绍了分析和理解用户影响的说明。
  • 将已知可靠用户添加到用户组并强制实施策略。

此过程有助于评估用户是否准备好执行令牌保护。

步骤 1:配置最终用户设备

请在每台设备上通过手动方式、组策略或 Intune 完成以下操作。

Windows操作系统

  1. 确保设备运行Windows 11 内部版本 26100.8246 / 26200.8246 或更高版本

  2. 通过设置以下注册表值启用此预览版:

    [HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\BrowserCore]
    "EnablePlatformAuth"=dword:00000001
    
  3. 安装 Microsoft 单点登录浏览器扩展:

    • Google Chrome:从 Chrome 网上应用店安装 Microsoft 单点登录,依次选择 添加到 Chrome>添加扩展程序,并确认其显示在工具栏中。
    • Microsoft Edge: 转到edge://extensions,打开允许来自其他应用商店的扩展,安装 Microsoft 单点登录扩展,并确认其已启用。

macOS

  1. 安装Microsoft 公司门户或通过 MDM 解决方案部署它。 公司门户充当Microsoft Entra登录的身份验证代理。
  2. 使用以下选项之一启用硬件支持的注册:
    • 选项 A:启用 Microsoft Enterprise SSO 插件
    • 选项 B:为 macOS 配置平台 SSO。 平台 SSO 默认使用硬件支持的存储,无需额外的标志配置。 有关设置说明,请参阅 Microsoft Intune 中为 macOS 设备配置平台 SSO。
  3. 按照前面的Windows部分所述,在 Microsoft Edge 或 Google Chrome 中安装Microsoft单一登录浏览器扩展。

步骤 1 之后的预期内容

设备满足先决条件和配置传播后,来自受支持应用程序和浏览器的身份验证请求将完全停止在浏览器中完成,而是由平台身份验证代理处理。 此行为允许这些应用程序使用设备绑定的登录会话令牌,例如 主刷新令牌(PRT),并满足令牌保护条件访问策略。

规划以下内容:

  • 请至少等待 24 小时,以使更改生效。 应用注册表值、扩展或 Platform SSO 配置文件后,不会立即切换为基于代理的身份验证。 在此窗口期结束之前,请勿进入第 2 步,否则仅报告数据将无法准确反映准备情况。
  • 在大多数情况下,转换是自动的。 用户通常不执行任何操作;更改传播时,现有浏览器会话将继续工作。
  • 某些用户会看到一个简短的登录对话框。 在预览期间,访问Azure门户的用户可能会短暂看到“登录...“消息,指出新窗口正在打开。 不会显示任何新窗口,无需用户操作,登录将自行完成。 (可选)提前将此行为传达给试点组,以便不会将其报告为失败。

步骤 2:在仅报告模式下创建条件访问策略

完成步骤 1 并等待 24 小时后,您可以继续以仅报告模式配置策略,以查看策略实施的准备情况。

  1. 以至少具有条件访问管理员角色的身份登录到 Microsoft Entra 管理中心。
  2. 转到 Entra ID>条件访问>策略,然后选择“新建策略”并为其命名。
  3. “分配”>用户下,添加试点用户或测试用户。 不要包含贵组织的紧急访问帐户或应急帐户。
  4. “目标资源”>“资源(以前称为云应用)”>“包括”>“选择资源”下,选择Windows Azure Service Management API
  5. “条件>设备”平台下,将“配置”设置为“是”,并包括WindowsmacOS 或两者。
  6. “条件>客户端”应用中,将 “配置 ”设置为 “是 ”,并包括 浏览器。 请确保不要为此预览版选择 移动应用和桌面客户端
  7. “访问控制>会话”下,选择“ 要求对登录会话使用令牌保护”,然后选择“ 选择”。
  8. “启用策略 ”设置为 “仅报告 ”,然后选择“ 创建”。

Tip

由于需要令牌保护的条件访问策略目前仅适用于Windows和 Apple 设备,因此当攻击者可能似乎来自其他平台时,必须保护环境免受潜在的策略绕过。

此外,还应配置以下策略:

步骤 3:使用日志和指标查看强制实施准备情况

在仅报告策略就位并运行后,应查看 策略影响,分析 登录日志,并使用 日志分析工具查看强制执行准备情况。

登录日志

若要查看管理中心中与令牌保护相关的登录事件,请执行以下作:

  1. 至少以条件访问管理员的身份登录到Microsoft Entra 管理中心
  2. 浏览到 Entra ID>监控和运行状况>登录日志
  3. 令牌保护 – 登录会话状态代码 列添加到视图中,快速查看相关的登录事件。 此外,筛选到Azure 资源管理器资源,并将客户端应用设置为 Browser,以隔离与此预览版相关的登录请求。
  4. 选择您正在研究的登录事件。
  5. 根据策略状态查看 条件访问仅报告 选项卡,并选择令牌保护策略。
  6. “会话控制”下,检查是否满足策略要求。
  7. 选择“ 基本信息 ”选项卡并选中 “令牌保护 - 登录会话 ”字段了解详细信息。

登录日志包括一个 tokenProtectionStatusDetails 属性,该属性指示请求是否使用设备绑定令牌:

"tokenProtectionStatusDetails": {
  "signInSessionStatus": "bound | unbound",
  "signInSessionStatusCode": <code>
}

注释

仅在 macOS 上,在强制实施令牌保护策略之前注册到Microsoft Entra ID的设备上的用户在强制实施策略后,系统会提示重新进行身份验证。 它们通过再次登录来完成一次性设备注册升级,以访问资源。 可以通过 状态代码 1003 和 1004 标识这些用户。 由于处于此状态的用户可以自行修正, 因此他们有资格实施策略

登录会话状态代码

若要了解请求为何显示为 未绑定 或标识可应用策略的用户,请参阅以下状态代码。

状态代码 Description 需要采取行动
1002 未绑定 – 由于缺少 Microsoft Entra ID 设备状态,请求处于未绑定状态。 用户必须注册或加入设备。
1003 未绑定 – 设备未使用安全凭据注册(旧版注册)。 Windows:此错误可能是由于设备注册类型不受支持,或者未使用全新登录凭据注册设备。
macOS: 用户执行一次性设备注册升级(可自行修复)。
1004 (仅限 macOS) 未绑定 - 设备注册不受硬件支持。 用户执行一次性设备注册升级(可自行修复)。
1005 未绑定 – 原因未指定。 视情况而定;请使用关联 ID 进行排查。
1006 未绑定 — 操作系统版本不受支持。 用户将 OS 升级到 Windows 11内部版本 26100.8246 / 26200.8246 或更高版本,或升级到受支持的 macOS 版本。
1007 未绑定 - 不受硬件支持;已登录用户不是已注册的设备所有者。 用户重新注册,或注册的所有者执行升级。
1008 未绑定 - 客户端不使用身份验证代理,例如 WAM。 客户端未与平台代理程序集成,或者未安装该代理程序或扩展。 对于浏览器,请安装并启用 Microsoft 单点登录扩展,并启用平台身份验证。

Tip

对于浏览器方案, 10081002 是载入过程中最常看到的代码。 这通常意味着 Microsoft 单点登录浏览器扩展缺失或已被禁用、未启用平台身份验证(在 Windows 上,EnablePlatformAuth 注册表值未设置)、正在使用不受支持的浏览器(如 Firefox 或 Safari),或者该应用不支持令牌保护。

识别可自行修复的用户(仅限 macOS)

在 macOS 上,代码 1003 和 1004 可通过一次性设备注册升级进行自我修复。

要识别符合要求或可通过用户操作升级的请求,请筛选以下条件:

  • signInSessionStatus == bound
  • signInSessionStatus == unbound配有signInSessionStatusCode10031004

非交互式登录的示例Microsoft Graph查询:

GET https://microsoftgraph.chinacloudapi.cn/beta/auditLogs/signIns?$filter=(
  signInEventTypes/any(t: t eq 'nonInteractiveUser')
  and resourceDisplayName eq 'Azure Resource Manager'
  and (tokenProtectionStatusDetails/signInSessionStatusCode eq 1003
    or tokenProtectionStatusDetails/signInSessionStatusCode eq 1004
    or tokenProtectionStatusDetails/signInSessionStatus eq 'bound'))

为这些用户强制实施令牌保护时,系统会提示他们再次登录,并在完成身份验证后访问资源。

Log Analytics

还可以使用 Log Analytics 查询因令牌保护强制实施失败而被阻止的请求对应的交互式和非交互式登录日志。 这些查询只是示例,可能会更改。 它们基于 Azure 资源管理器 资源进行筛选,并添加就绪情况指标,以便你区分硬性阻止项和可自行修复的问题。

按应用程序发出的请求

以下示例查询会搜索最近七天的非交互式登录日志,按应用程序突出显示对 ARM 的已阻止请求与已允许请求,并标记用户可自行修复的阻止情况。 改用SigninLogs来查看交互式浏览器登录。

// Select the log to query (SigninLogs or AADNonInteractiveUserSignInLogs)
// SigninLogs
AADNonInteractiveUserSignInLogs
// Adjust the time range below
| where TimeGenerated > ago(7d)
| project Id, ConditionalAccessPolicies, Status, UserPrincipalName, AppDisplayName,
    ResourceDisplayName, TokenProtectionStatusDetails
| where ConditionalAccessPolicies != "[]"
| where ResourceDisplayName == "Azure Resource Manager"
// Add UserPrincipalName if you want to filter to a specific user
// | where UserPrincipalName == "<user_principal_name>"
| mv-expand todynamic(ConditionalAccessPolicies)
| where ConditionalAccessPolicies["enforcedSessionControls"] contains '["Binding"]'
    or ConditionalAccessPolicies["enforcedSessionControls"] contains '["SignInTokenProtection"]'
| where ConditionalAccessPolicies.result != "reportOnlyNotApplied"
    and ConditionalAccessPolicies.result != "notApplied"
| extend SessionNotSatisfyResult = ConditionalAccessPolicies["sessionControlsNotSatisfied"]
| extend Result = case(
    SessionNotSatisfyResult contains 'SignInTokenProtection'
        or SessionNotSatisfyResult contains 'Binding', 'Block', 'Allow')
| extend parsedBindingDetails = parse_json(TokenProtectionStatusDetails)
| extend bindingStatusCode = tostring(parsedBindingDetails["signInSessionStatusCode"])
| extend IsSelfRemediable = Result == "Block"
    and (bindingStatusCode == "1003" or bindingStatusCode == "1004")
| summarize by Id, UserPrincipalName, AppDisplayName, Result, IsSelfRemediable
| summarize Requests = count(),
    Users = dcount(UserPrincipalName),
    Allow = countif(Result == "Allow"),
    Block = countif(Result == "Block"),
    BlockSelfRemediable = countif(IsSelfRemediable == true),
    BlockedUsers = dcountif(UserPrincipalName, Result == "Block"),
    BlockedUsersSelfRemediable = dcountif(UserPrincipalName, IsSelfRemediable == true)
    by AppDisplayName
| extend PctAllowed = round(100.0 * Allow / (Allow + Block), 2)
| extend PctEnforceable = round(100.0 * (Allow + BlockSelfRemediable) / (Allow + Block), 2)
| project AppDisplayName, Requests, Users, Allow, Block,
    BlockSelfRemediable, BlockedUsers, BlockedUsersSelfRemediable,
    PctAllowed, PctEnforceable
| sort by Requests desc
用户请求

以下查询查看过去七天的非交互式登录日志,其中突出显示了用户对 ARM 的阻止请求与允许的请求,并使用相同的可自行修复和可强制执行的指标。

// Per-user query for the Azure portal -> ARM web app scenario
// SigninLogs
AADNonInteractiveUserSignInLogs
// Adjust the time range below
| where TimeGenerated > ago(7d)
| project Id, ConditionalAccessPolicies, UserPrincipalName, AppDisplayName,
    ResourceDisplayName, TokenProtectionStatusDetails
| where ConditionalAccessPolicies != "[]"
| where ResourceDisplayName == "Azure Resource Manager"
// Add UserPrincipalName if you want to filter to a specific user
// | where UserPrincipalName == "<user_principal_name>"
| mv-expand todynamic(ConditionalAccessPolicies)
| where ConditionalAccessPolicies["enforcedSessionControls"] contains '["Binding"]'
    or ConditionalAccessPolicies["enforcedSessionControls"] contains '["SignInTokenProtection"]'
| where ConditionalAccessPolicies.result != "reportOnlyNotApplied"
    and ConditionalAccessPolicies.result != "notApplied"
| extend SessionNotSatisfyResult = ConditionalAccessPolicies.sessionControlsNotSatisfied
| extend Result = case(
    SessionNotSatisfyResult contains 'SignInTokenProtection'
        or SessionNotSatisfyResult contains 'Binding', 'Block', 'Allow')
| extend parsedBindingDetails = parse_json(TokenProtectionStatusDetails)
| extend bindingStatusCode = tostring(parsedBindingDetails["signInSessionStatusCode"])
| extend IsSelfRemediable = Result == "Block"
    and (bindingStatusCode == "1003" or bindingStatusCode == "1004")
| summarize by Id, UserPrincipalName, AppDisplayName, ResourceDisplayName, Result, IsSelfRemediable
| summarize Requests = count(),
    Allow = countif(Result == "Allow"),
    Block = countif(Result == "Block"),
    BlockSelfRemediable = countif(IsSelfRemediable == true)
    by UserPrincipalName, AppDisplayName, ResourceDisplayName
| extend PctAllowed = round(100.0 * Allow / (Allow + Block), 2)
| extend PctEnforceable = round(100.0 * (Allow + BlockSelfRemediable) / (Allow + Block), 2)
| project UserPrincipalName, AppDisplayName, ResourceDisplayName,
    Requests, Allow, Block, BlockSelfRemediable,
    PctAllowed, PctEnforceable
| sort by UserPrincipalName asc

步骤 4:强制实施策略

查看登录日志数据并确认目标用户和设备已准备就绪后,将 启用策略 的切换按钮从仅报告 切换为开启