在本地开发期间,使用服务主体对 Azure 服务进行 Go 应用认证。

在本地开发期间,应用程序需要向 Azure 进行身份验证才能访问各种 Azure 服务。 本地身份验证的两种常见方法是 使用开发人员帐户 或服务主体。 本文介绍如何使用应用程序服务主体。 在以下部分中,你将了解:

  • 如何使用 Microsoft Entra 注册应用程序以创建服务主体
  • 如何使用 Microsoft Entra 组高效管理权限
  • 如何将角色分配到范围权限
  • 如何使用应用代码中的服务主体进行身份验证

通过使用专用的应用服务主体,您可以在访问 Azure 资源时遵循最低特权原则。 在开发期间,将权限限制为应用的特定要求,防止意外访问适用于其他应用或服务的 Azure 资源。 此方法还有助于避免在应用移至生产环境时出现的问题,确保其在开发环境中不拥有过多权限。

显示本地 Go 应用如何使用服务主体连接到 Azure 资源的关系图。

在 Azure 中注册应用时,需创建应用程序服务主体。 对于本地开发:

  • 为每个在应用上运行的开发人员创建单独的应用注册,以便每个开发人员都有自己的应用程序服务主体,无需共享凭据。
  • 为每个应用创建单独的应用注册,以仅将应用的权限限制为必需内容。

在本地开发期间,使用应用程序服务主体的标识设置环境变量。 Azure 标识库读取这些环境变量,以向所需的 Azure 资源对应用进行身份验证。

在 Azure 中注册应用

使用 Azure 门户或 Azure CLI 通过 Azure 中的应用注册创建应用程序服务主体对象。

  1. 在 Azure 门户中,使用搜索栏导航到 应用注册 页。

  2. 在“应用注册”页上,选择“+ 新建注册”

  3. 在“注册应用程序”页面上:

    • 对于 名称 字段,请输入包含应用名称和目标环境的描述性值。
    • 对于支持的帐户类型,请仅选择此组织目录中的帐户(仅限 Microsoft 客户引导 - 单租户),或选择最能满足你的要求的选项。
  4. 选择 注册 以注册应用并创建服务主体。

    显示如何在 Azure 门户中创建应用注册的屏幕截图。

  5. 在应用的 应用注册 页上,复制 应用程序(客户端)ID目录(租户)ID 并将其粘贴到临时位置,以便在应用代码配置中稍后使用。

  6. 选择“添加证书或机密”以设置应用的凭据。

  7. 证书 & 机密 页上,选择 + 新建客户端密码

  8. 在打开的“添加客户端机密”打开的弹出面板中:

    • 对于“说明”,请输入“当前”作为值。
    • 对于“过期”值,请保留默认建议值 180 天。
    • 选择“”,然后选择“”以添加密钥。
  9. 证书 & 密钥 页上,复制客户端密钥的 Value 属性,以便在将来的步骤中使用。

    注释

    创建应用注册后,客户端机密值仅显示一次。 无需使此客户端密码失效即可添加更多客户端机密,但无法再次显示此值。

创建用于本地开发的Microsoft Entra 组

创建Microsoft Entra 组来封装应用在本地开发中所需的角色(权限),而不是将角色分配给单个服务主体对象。 此方法具有以下优势:

  • 每个开发人员在组级别都分配了相同的角色。
  • 如果应用需要新角色,只需将角色添加到应用的组中。
  • 如果新开发人员加入团队,则会为开发人员创建一个新的应用程序服务主体并将其添加到组中,确保开发人员有权处理应用。
  1. 导航到 Azure 门户中 Microsoft Entra ID 概述页。

  2. 从左侧菜单中选择 “所有组 ”。

  3. “组 ”页上,选择“ 新建组”。

  4. “新建组 ”页上,填写以下表单字段:

    • “组类型”:选择“安全性”。
    • 组名称:输入包含对应用或环境名称的引用的组的名称。
    • 组说明:输入用于解释该组目的的说明。

    显示如何在 Azure 门户中创建组的屏幕截图。

  5. 在“成员”下选择“未选择成员”链接,以将成员添加到组中

  6. 在打开的浮出控件面板中,搜索之前创建的服务主体,并从筛选的结果中选择它。 选择面板底部的 “选择 ”按钮以确认你的选择。

  7. 选择“新建组”页底部的“创建”以创建组并返回到“所有组”页。 如果未看到列出的新组,请稍等片刻并刷新页面。

将角色分配给组

接下来,确定您的应用在何种资源上需要哪些角色(权限),并将这些角色分配给您创建的 Microsoft Entra 组。 可以在资源、资源组或订阅范围内为组分配角色。 此示例演示如何在资源组范围内分配角色,因为大多数应用将其所有 Azure 资源分组到单个资源组中。

  1. 在 Azure 门户中,导航到包含应用的资源组的 “概述 ”页。

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

  3. “访问控制”(IAM) 页上,选择“ + 添加 ”,然后从下拉菜单中选择 “添加角色分配 ”。 “添加角色分配”页提供了多个选项卡来配置和分配角色。

  4. 在“ 角色 ”选项卡上,使用搜索框查找要分配的角色。 选择角色,然后选择“ 下一步”。

  5. 在“ 成员 ”选项卡上:

    • 对于 “分配对值的访问权限 ”,请选择“ 用户”、“组”或服务主体
    • 对于 “成员 ”值,选择 “+ 选择成员 ”以打开 “选择成员 ”浮出控件面板。
    • 搜索之前创建的Microsoft Entra 组,并从筛选的结果中选择它。 选择 “选择” 以选择组并关闭浮动面板。
    • 选择“成员”选项卡底部的“审阅 + 分配”。

    显示如何为 Microsoft Entra 组分配角色的屏幕截图。

  6. 在“ 审阅 + 分配 ”选项卡上,选择页面底部的 “审阅 + 分配 ”。

设置应用环境变量

在运行时,Azure 标识库中的某些凭据(例如DefaultAzureCredentialEnvironmentCredential,和ClientSecretCredential)根据环境变量中的约定搜索服务主体信息。 可以根据工具和环境以多种方式配置环境变量。 可以在开发过程中创建 .env 文件或使用系统环境变量在本地存储这些凭据。 开发过程中,由于大多数开发人员处理多个应用程序,可以使用类似 godotenv 的包,从存储在应用程序目录中的 .env 文件访问环境变量。 此方法将用于对应用程序进行身份验证的环境变量限定为 Azure,以便只有此应用程序可以使用它们。 切勿将 .env 文件提交到源代码管理,因为它包含 Azure 的应用程序秘密密钥。 Go 的标准 .gitignore 文件会自动从签入中排除该 .env 文件。

若要使用该 godotenv 包,请先在应用程序中安装该包。

go get github.com/joho/godotenv

然后,在应用程序根目录中创建一个 .env 文件。 使用从服务主体的应用注册过程获取的值设置环境变量值:

  • AZURE_CLIENT_ID:用于标识 Azure 中注册的应用。
  • AZURE_TENANT_ID:Microsoft Entra 租户的 ID。
  • AZURE_CLIENT_SECRET:为应用生成的机密凭据。
AZURE_CLIENT_ID=<your-client-id>
AZURE_TENANT_ID=<your-tenant-id>
AZURE_CLIENT_SECRET=<your-client-secret>

最后,在应用程序的启动代码中,使用 godotenv 库从启动时从 .env 文件中读取环境变量。

// Imports of fmt, log, and os omitted for brevity 
import "github.com/joho/godotenv"

environment := os.Getenv("ENVIRONMENT")

if environment == "development" {
	fmt.Println("Loading environment variables from .env file")

	// Load the .env file
	err := godotenv.Load(".env")
	if err != nil {
	    log.Fatalf("Error loading .env file: %v", err)
	}
}

如果想要在系统环境中设置环境变量,而不是使用 .env 文件,可以根据作系统和 shell 以多种方式执行此作。 以下示例演示如何在不同的 shell 中设置环境变量:

export AZURE_CLIENT_ID=<your-client-id>
export AZURE_TENANT_ID=<your-tenant-id>
export AZURE_CLIENT_SECRET=<your-client-secret>

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

Azure 标识库为各种方案和Microsoft Entra 身份验证流提供不同的 TokenCredential 实现。 本地和生产环境中使用服务主体时,请使用 EnvironmentCredential。 在此方案中, EnvironmentCredential 读取环境变量 AZURE_CLIENT_IDAZURE_TENANT_IDAZURE_CLIENT_SECRET 获取要连接到 Azure 的应用程序服务主体信息。

  1. azidentity 包添加到应用程序。

    go get github.com/Azure/azure-sdk-for-go/sdk/azidentity
    
  2. 对于在应用中创建 Azure SDK 客户端对象的任何 Go 代码,需要:

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

    以下代码段显示了一个示例:

    import (
    	"context"
    	"os"
    
    	"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.NewEnvironmentCredential(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>)
    }