如何使用应用服务和 Azure Functions 的托管标识

本文介绍如何为应用服务和 Azure Functions 应用程序创建托管标识,以及如何使用它来访问其他资源。

重要

如果应用跨订阅/租户迁移,应用服务和 Azure Functions 的托管标识将不会按预期工作。 应用需要获取新标识,这可以通过禁用并重新启用该功能来完成。 下游资源还需要更新访问策略才能使用新标识。

借助 Azure Active Directory (Azure AD) 的托管标识,应用可以轻松访问其他受 Azure AD 保护的资源(如 Azure Key Vault)。 标识由 Azure 平台托管,无需设置或转交任何机密。 有关 Azure AD 中的托管标识的详细信息,请参阅 Azure 资源的托管标识

你的应用程序可以被授予两种类型的标识:

  • 系统分配的标识与你的应用程序相绑定,如果删除应用,标识也会被删除。 一个应用只能具有一个系统分配的标识。
  • 用户分配的标识是可以分配给应用的独立 Azure 资源。 一个应用可以具有多个用户分配的标识。

添加系统分配的标识

  1. 在应用页面的左侧导航中,向下滚动到“设置”组。

  2. 选择“标识”。

  3. 在“系统分配的”选项卡中,将“状态”切换为“启用” 。 单击“保存” 。

    屏幕截图显示了在何处将“状态”切换为“启用”,然后选择“保存”。

注意

若要在 Azure 门户中查找 Web 应用或槽应用的托管标识,请在“企业应用程序”下查看“用户设置”部分。 通常,槽名称与 <app name>/slots/<slot name> 类似。

添加用户分配的标识

创建带有用户分配符的标识的应用需要创建标识,然后将其资源标识符添加到应用配置中。

首先,需要创建用户分配的标识资源。

  1. 创建用户分配的托管标识资源。

  2. 在应用页面的左侧导航中,向下滚动到“设置”组。

  3. 选择“标识”。

  4. 在“用户分配”选项卡中,单击“添加” 。

  5. 搜索之前创建的标识并选择它。 单击“添加”。

    应用服务中的托管标识

重要

如果在选择要添加的用户分配的标识后选择“添加”,则应用程序将重启。

配置目标资源

可能需要配置目标资源,允许从应用或 Functions 进行访问。 例如,如果你请求令牌以访问 Key Vault,则还必须添加一个访问策略,其中包括你的应用或 Functions 的托管身份。 否则,对 Key Vault 的调用将被拒绝,即使你使用了有效令牌。 Azure SQL 数据库也是如此。 若要详细了解支持 Azure Active Directory 令牌的资源,请参阅支持 Azure AD 身份验证的 Azure 服务

重要

用于托管标识的后端服务将为每个资源 URI 维护缓存约 24 小时。 如果你更新特定目标资源的访问策略并立即检索该资源的令牌,则可以继续获取具有过时权限的缓存令牌,直到该令牌过期。 目前无法强制刷新令牌。

在应用代码中连接到 Azure 服务

借助其托管标识,应用可以获取受 Azure Active Directory 保护的 Azure 资源的令牌,例如 Azure SQL 数据库、Azure Key Vault 和 Azure 存储。 这些令牌代表访问资源的应用程序,而不是应用程序的任何特定用户。

应用服务和 Azure Functions 提供了内部可访问的 REST 终结点以用于检索令牌。 可以使用标准 HTTP GET 从应用中访问 REST 终结点,该标准可以使用每种语言的通用 HTTP 客户端来实现。 对于 .NET、JavaScript、Java 和 Python,Azure 标识客户端库提供了基于此 REST 终结点的抽象,并简化了开发体验。 连接到其他 Azure 服务非常简单,只需要将凭据对象添加到特定于服务的客户端。

原始的 HTTP GET 请求如以下示例所示:

GET /MSI/token?resource=https://vault.azure.cn&api-version=2019-08-01 HTTP/1.1
Host: localhost:4141
X-IDENTITY-HEADER: 853b9a84-5bfa-4b22-a3f3-0b9a43d9ad8a

示例响应可能如下例所示:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "access_token": "eyJ0eXAi…",
    "expires_on": "1586984735",
    "resource": "https://vault.azure.cn",
    "token_type": "Bearer",
    "client_id": "5E29463D-71DA-4FE0-8E69-999B57DB23B0"
}

此响应与 Azure AD 服务到服务访问令牌请求的响应相同。 要访问 Key Vault,你需要将 access_token 的值添加到与 Vault 的客户端连接。

有关 REST 终结点的更多信息,请参阅 REST 终结点参考

删除标识

删除系统分配的标识时,会从 Azure Active Directory 中删除标识。 你删除应用资源本身时,系统分配的标识也会自动从 Azure Active Directory 中删除。

  1. 在应用页面的左侧导航中,向下滚动到“设置”组。

  2. 选择“标识”。 然后,根据标识类型执行以下步骤:

    • 系统分配的标识:在“系统分配”选项卡中,将“状态”切换为“关闭”。 单击“保存” 。
    • 用户分配的标识:单击“用户分配”选项卡,选中该标识的复选框,然后单击“删除”。 单击“是” 以确认。

注意

还可以设置一个应用程序设置 (WEBSITE_DISABLE_MSI),它只禁用本地令牌服务。 但是,它会保留标识,而工具仍会将托管标识显示为“打开”或“已启用”。因此,不建议使用此设置。

REST 终结点参考

具有托管标识的应用通过定义两个环境变量使此终结点可用:

  • IDENTITY_ENDPOINT - 本地令牌服务的 URL。
  • IDENTITY_HEADER - 用于帮助缓解服务器端请求伪造 (SSRF) 攻击的标头。 该值由平台轮换。

IDENTITY_ENDPOINT 是一个本地 URL,应用可从其请求令牌。 若要获取资源的令牌,请对此终结点发起 HTTP GET 请求,并包括以下参数:

参数名称 In 说明
resource 查询 应获取其令牌的资源的 Azure AD 资源 URI。 这可以是支持 Azure AD 身份验证的 Azure 服务或任何其他资源 URI 之一。
api-version 查询 要使用的令牌 API 版本。 请使用 2019-08-01
X-IDENTITY-HEADER 标头 IDENTITY_HEADER 环境变量的值。 此标头用于帮助缓解服务器端请求伪造 (SSRF) 攻击。
client_id 查询 (可选)要使用的用户分配的标识的客户端 ID。 不能在包含 principal_idmi_res_idobject_id 的请求中使用。 如果省略所有 ID 参数(client_idprincipal_idobject_idmi_res_id),则使用系统分配的标识。
principal_id 查询 (可选)要使用的用户分配的标识的主体 ID。 object_id 是可以改用的别名。 不能在包含 client_id、mi_res_id 或 object_id 的请求中使用。 如果省略所有 ID 参数(client_idprincipal_idobject_idmi_res_id),则使用系统分配的标识。
mi_res_id 查询 (可选)要使用的用户分配的标识的 Azure 资源 ID。 不能在包含 principal_idclient_idobject_id 的请求中使用。 如果省略所有 ID 参数(client_idprincipal_idobject_idmi_res_id),则使用系统分配的标识。

重要

如果你要尝试获取用户分配的标识的令牌,必须包含一个可选属性。 否则,令牌服务将尝试为系统分配的标识获取令牌,而该令牌不一定存在。

后续步骤