使用系统分配的托管标识向 Azure 资源验证 Azure 托管的 Go 应用

向其他 Azure 资源验证 Azure 托管应用的建议方法是使用 托管标识。 大多数 Azure 服务都支持此方法,包括 Azure 应用服务、Azure 容器应用和 Azure 虚拟机上托管的应用。 在 身份验证概述 页上详细了解不同的身份验证技术和方法。 在前面的部分中,你将了解:

  • 基本托管标识概念
  • 如何为应用创建系统分配的托管标识
  • 如何将角色分配给系统分配的托管标识
  • 如何通过应用代码使用系统分配的托管标识进行身份验证

基本托管标识概念

托管标识使应用能够安全地连接到其他 Azure 资源,而无需使用密钥或其他应用程序机密。 在内部,Azure 会跟踪标识及其允许连接到的资源。 Azure 使用此信息自动获取应用的 Microsoft Entra 令牌,以允许它连接到其他 Azure 资源。

配置托管应用时,需要考虑两种类型的托管标识:

  • 系统分配的 托管标识直接在 Azure 资源上启用,并绑定到其生命周期。 当资源被删除时,Azure 会自动为你删除标识。 系统分配的标识提供了使用托管标识的极简方法。
  • 用户分配的 托管标识创建为独立的 Azure 资源,并提供更大的灵活性和功能。 它们非常适合涉及多个需要共享相同标识和权限的 Azure 资源的解决方案。 例如,如果多个虚拟机需要访问同一组 Azure 资源,则用户分配的托管标识可提供可重用性和优化管理。

小窍门

在托管标识 最佳做法建议 文章中,详细了解如何选择和管理系统分配的托管标识和用户分配的托管标识。

以下部分介绍了为 Azure 托管应用启用和使用系统分配的托管标识的步骤。 如果需要使用用户分配的托管标识,请访问 用户分配的托管标识 文章以了解详细信息。

在 Azure 托管资源上启用系统分配的托管标识

若要开始在应用中使用系统分配的托管标识,请在托管应用的 Azure 资源上启用标识,例如 Azure 应用服务、Azure 容器应用或 Azure 虚拟机。

可以使用 Azure 门户或 Azure CLI 为 Azure 资源启用系统分配的托管标识。

  1. 在 Azure 门户中,导航到托管应用程序代码的资源,例如 Azure 应用服务或 Azure 容器应用实例。

  2. 在资源的 “概述 ”页中,展开 “设置” ,然后从导航中选择“ 标识 ”。

  3. “标识 ”页上,将 “状态 ”滑块切换为 “打开”。

  4. 选择保存以应用更改。

    显示如何在容器应用中启用系统分配的托管标识的屏幕截图。

为托管标识分配角色

接下来,确定应用需要哪些角色并将这些角色分配给托管标识。 可以在以下范围内将角色分配到托管标识:

  • 资源:分配的角色仅适用于该特定资源。
  • 资源组:分配的角色适用于资源组中包含的所有资源。
  • 订阅:分配的角色适用于订阅中包含的所有资源。

以下示例演示如何在资源组范围内分配角色,因为许多应用使用单个资源组管理其所有相关的 Azure 资源。

  1. 导航到包含具有系统分配托管标识的应用的资源组的 “概述 ”页。

  2. 在左侧导航中选择 “访问控制”(IAM )。

  3. “访问控制”(IAM) 页上,选择顶部菜单中的“ + 添加 ”,然后选择“ 添加角色分配 ”以导航到 “添加角色分配 ”页。

    显示如何访问标识角色分配页的屏幕截图。

  4. “添加角色分配”页提供了一个选项卡式的多步骤工作流,用于将角色分配给标识。 在“初始 角色 ”选项卡上,使用顶部的搜索框找到要分配给标识的角色。

  5. 从结果中选择角色,然后选择“ 下一步 ”以移动到“ 成员 ”选项卡。

  6. 对于 “分配访问权限” 选项,请选择 “托管标识”。

  7. 对于“ 成员 ”选项,选择“ + 选择成员 ”以打开 “选择托管标识 ”面板。

  8. “选择托管标识 ”面板中,使用 “订阅 ”和 “托管标识 ”下拉列表筛选标识的搜索结果。 使用 “选择 搜索”框查找为托管应用的 Azure 资源启用的系统标识。

    显示托管标识分配过程的屏幕截图。

  9. 选择标识,然后选择面板底部的 “选择” 以继续。

  10. 选择页面底部的 “查看 + 分配 ”。

  11. 在“最终 审阅 + 分配 ”选项卡上,选择“ 审阅 + 分配 ”以完成工作流。

从应用向 Azure 服务进行身份验证

azidentity 模块提供各种凭据,这些凭据的实现适用于支持不同方案和Microsoft Entra 身份验证流TokenCredential。 由于托管标识在本地运行时不可用,因此后续步骤演示了在哪种方案中要使用的凭据:

  • 本地开发环境仅在本地开发期间,使用DefaultAzureCredential作为推荐的预配置凭据链。 DefaultAzureCredential 从本地开发工具(如 Azure CLI)检测用户凭据。 它还为重试、响应等待时间以及支持多个身份验证选项提供了灵活性和便利。 访问 本地开发期间对 Azure 服务的身份验证 文章以了解详细信息。
  • Azure 托管的应用:在 Azure 中运行应用时,请使用 ManagedIdentityCredential 安全地发现为应用配置的托管标识。 指定此确切类型的凭据可防止意外选取其他可用凭据。

实现代码

添加 azidentity 模块。

在所选终端中,导航到应用程序项目目录并运行以下命令:

go get github.com/Azure/azure-sdk-for-go/sdk/azidentity

可以使用各种 Azure SDK 客户端库中的专用客户端访问 Azure 服务。 对于在应用中实例化 Azure SDK 客户端的任何 Go 代码,您需要:

  1. azidentity导入包。
  2. 创建DefaultAzureCredential类型的实例。
  3. 将类型实例 DefaultAzureCredential 传递给 Azure SDK 客户端构造函数。

以下步骤的示例显示在以下代码段中,其中包含 Azure 存储 Blob 客户端。

import (
	"context"
	"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
	"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob"
)

const (
	account       = "https://<replace_with_your_storage_account_name>.blob.core.windows.net/"
	containerName = "sample-container"
	blobName      = "sample-blob"
	sampleFile    = "path/to/sample/file"
)

func main() {
	// create a credential
	cred, err := azidentity.NewDefaultAzureCredential(nil)
	if err != nil {
	  // TODO: handle error
	}

	// create a client for the specified storage account
	client, err := azblob.NewClient(account, cred, nil)
	if err != nil {
	  // TODO: handle error
	}

	// TODO: perform some action with the azblob Client
	// _, err = client.DownloadFile(context.TODO(), <containerName>, <blobName>, <target_file>, <DownloadFileOptions>)
}

Azure SDK for Go 身份验证概述 文章中所述, DefaultAzureCredential 支持多种身份验证方法并确定在运行时使用的身份验证方法。 此方法的好处是,你的应用可以在不同的环境中使用不同的身份验证方法,而无需实现特定于环境的代码。 在本地开发期间,在工作站上运行上述代码时, DefaultAzureCredential 使用应用程序服务主体(由环境设置确定)或开发人员工具凭据来与其他 Azure 资源进行身份验证。 因此,相同的代码可用于在本地开发期间和部署到 Azure 时向 Azure 资源验证应用。

重要

DefaultAzureCredential 通过将 Azure 托管环境中的凭据与本地开发中使用的凭据结合在一起,从而在开发部署到 Azure 的应用程序时简化身份验证。 在生产环境中,最好使用特定的凭据类型,以便身份验证更具可预测性且更易于调试。

另一种替代 DefaultAzureCredential 方法是使用 ManagedIdentityCredential。 使用 ManagedIdentityCredential 的步骤与使用 DefaultAzureCredential 类型的步骤相同。

以下步骤的示例显示在以下代码段中,其中包含 Azure 存储 Blob 客户端。

import (
	"context"
	"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
	"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob"
)

const (
                    // Replace placeholder text with your storage account name
	account       = "https://<replace_with_your_storage_account_name>.blob.core.windows.net/"
	containerName = "sample-container"
	blobName      = "sample-blob"
	sampleFile    = "path/to/sample/file"
)

func main() {
	// create a credential
	cred, err := azidentity.NewManagedIdentityCredential(nil)
	
	// When using User Assigned Managed Identity use this instead and pass your client id in the options
	// clientID := azidentity.ClientID("abcd1234-...")
	// opts := azidentity.ManagedIdentityCredentialOptions{ID: clientID}
	// cred, err := azidentity.NewManagedIdentityCredential(&opts)
	
	if err != nil {
	  // TODO: handle error
	}
	
	// create a client for the specified storage account
	client, err := azblob.NewClient(account, cred, nil)
	if err != nil {
	  // TODO: handle error
	}
	
	// TODO: perform some action with the azblob Client
	// _, err = client.DownloadFile(context.TODO(), <containerName>, <blobName>, <target_file>, <DownloadFileOptions>)
}

上述代码的行为因运行环境而异:

  • 在本地开发工作站上, DefaultAzureCredential 查找应用程序服务主体的环境变量,或在本地安装的开发人员工具(如 Azure CLI)中查找一组开发人员凭据。
  • 部署到 Azure 时, ManagedIdentityCredential 发现托管标识配置以自动向其他服务进行身份验证。