使用服务主体进行 Azure SDK for Go 身份验证
在本教程中,你将使用 Azure SDK for Go 通过机密或证书通过 Azure 服务主体向 Azure 进行身份验证。
Azure 服务主体定义 Microsoft Entra 租户中的访问策略和权限,从而在登录期间启用身份验证和资源访问期间授权等核心功能。 他们无需使用个人帐户来访问 Azure 资源。 你可以为服务主体分配应用所需的确切权限,并针对这些权限进行开发,而不是使用租户中可能比应用所需的权限更多的个人帐户。 还可以将服务主体用于托管在本地且需要使用 Azure 资源的应用。 Azure SDK for Go Azure 标识 模块提供了一种使用环境变量和机密或证书通过服务主体向 Azure 进行身份验证的便捷方法。
按照此教程,使用服务主体创建 Azure SDK for Go 并向其进行身份验证。
先决条件
- Azure 订阅:如果没有 Azure 订阅,请在开始之前创建一个免费帐户。
已安装 Go:版本 1.18 或更高版本
若要使用 Azure CLI 运行本文中的步骤:
在 Azure Cloud Shell 中使用 Bash 环境。 有关详细信息,请参阅 Azure Cloud Shell 中的 Bash 快速入门。
如需在本地运行 CLI 参考命令,请安装 Azure CLI。 如果在 Windows 或 macOS 上运行,请考虑在 Docker 容器中运行 Azure CLI。 有关详细信息,请参阅如何在 Docker 容器中运行 Azure CLI。
如果使用的是本地安装,请使用 az login 命令登录到 Azure CLI。 若要完成身份验证过程,请遵循终端中显示的步骤。 有关其他登录选项,请参阅使用 Azure CLI 登录。
出现提示时,请在首次使用时安装 Azure CLI 扩展。 有关扩展详细信息,请参阅使用 Azure CLI 的扩展。
运行 az version 以查找安装的版本和依赖库。 若要升级到最新版本,请运行 az upgrade。
若要使用 Azure PowerShell 运行本文中的步骤:
- 如果选择在本地使用 Azure PowerShell:
- 安装最新版本的 Az PowerShell 模块。
- 使用 Connect-AzAccount cmdlet 连接到 Azure 帐户。
- 如果选择使用 Azure Cloud Shell:
- 有关详细信息,请参阅 Azure Cloud Shell 概述。
- 如果选择在本地使用 Azure PowerShell:
1.创建 Azure 资源
在开始之前,请创建新的资源组和密钥保管库实例。
az group create --name go-on-azure --location eastus
az keyvault create --location eastus --name <keyVaultName> --resource-group go-on-azure --enable-rbac-authorization
将 <keyVaultName>
替换为全局唯一名称。
记下 id
命令输出中的 az keyvault create
属性。 在下一部分中,你将使用它来定义服务主体的授权范围。 该值id
采用以下形式: /subscriptions/<subscriptionId>/resourceGroups/go-on-azure/providers/Microsoft.KeyVault/vaults/<keyVaultName>
2. 创建 Azure 服务主体
使用以下方法之一创建 Azure 服务主体,并在密钥保管库上为其分配“密钥库机密办公室r”角色:
要详细了解 Azure 服务主体,请参阅服务主体对象。
将“密钥库机密办公室r”角色分配给服务主体,授权它在密钥保管库中创建、读取、更新和删除机密。 若要详细了解 Azure 密钥保管库的内置角色,请参阅使用 Azure 基于角色的访问控制提供对密钥库密钥、证书和机密的访问权限。 若要详细了解 Azure 中的内置角色,请参阅 Azure 内置角色。
选项 1:使用机密创建 Azure 服务主体
运行以下命令以创建 Azure 服务主体,并在密钥保管库上为其分配“密钥库机密办公室r”角色。
az ad sp create-for-rbac --name <servicePrincipalName> --role "Key Vault Secrets Officer" --scope <keyVaultId>
将 <servicePrincipalName>
和 <keyVaultId>
替换为相应的值。
记下输出中的 password
属性 tenant
和 appId
属性。 下一部分需要这些信息。
创建后,无法检索服务主体密码。 如果忘记了密码,可以 重置服务主体凭据。
选项 2:使用证书创建 Azure 服务主体
运行以下命令,创建使用证书的 Azure 服务主体,并在密钥保管库上为其分配“密钥库机密办公室r”角色。
az ad sp create-for-rbac --name <servicePrincipalName> --create-cert --role "Key Vault Secrets Officer" --scope <keyVaultId>
将 <servicePrincipalName>
和 <keyVaultId>
替换为相应的值。
记下输出中的 fileWithCertAndPrivateKey
属性 tenantId
和 appId
属性。 下一部分需要这些信息。
3. 使用服务主体向 Azure 进行身份验证
通过使用 DefaultAzureCredential
,可以避免编写特定于环境的代码以向 Azure 进行身份验证。 通过 DefaultAzureCredential
定义环境变量,可以配置服务主体凭据。
选择以下选项之一来配置服务主体凭据:
要了解有关 DefaultAzureCredential
的详细信息,请参阅使用 Azure SDK for Go 进行 Azure 身份验证
选项 1:使用机密进行身份验证
定义以下环境变量:
变量名称 | 值 |
---|---|
AZURE_CLIENT_ID |
Azure 服务主体的应用程序 ID |
AZURE_TENANT_ID |
应用程序的 Microsoft Entra 租户的 ID |
AZURE_CLIENT_SECRET |
Azure 服务主体的密码 |
export AZURE_TENANT_ID="<active_directory_tenant_id>"
export AZURE_CLIENT_ID="<service_principal_appid>"
export AZURE_CLIENT_SECRET="<service_principal_password>"
选项 2:使用证书进行身份验证
变量名称 | 值 |
---|---|
AZURE_CLIENT_ID |
Azure 服务主体的应用程序 ID |
AZURE_TENANT_ID |
应用程序的 Microsoft Entra 租户的 ID |
AZURE_CLIENT_CERTIFICATE_PATH |
PEM 或 PKCS12 证书文件的路径,包括私钥。 如果遵循了 Azure CLI 的步骤,则该文件不受密码保护。 如果遵循 Azure PowerShell 的步骤,则该文件受密码保护,还需要设置 AZURE_CLIENT_CERTIFICATE_PASSWORD 环境变量。 |
AZURE_CLIENT_CERTIFICATE_PASSWORD |
创建服务主体时输入的密码。 仅当遵循 Azure PowerShell 的步骤时才需要。 |
export AZURE_TENANT_ID="<active_directory_tenant_id>"
export AZURE_CLIENT_ID="<service_principal_appid>"
export AZURE_CLIENT_CERTIFICATE_PATH="<azure_client_certificate_path>"
使用 DefaultAzureCredential 对资源客户端进行身份验证
设置环境变量后,可以在 DefaultAzureCredential
Azure 标识模块中使用对资源客户端进行身份验证。 以下代码演示如何获取 . 的 DefaultAzureCredential
实例。
cred, err := azidentity.NewDefaultAzureCredential(nil)
if err != nil {
log.Fatalf("failed to obtain a credential: %v", err)
}
4. 使用 Go 创建密钥保管库机密
使用以下代码示例验证服务主体是否向 Azure 进行身份验证,并具有对密钥保管库的适当权限。
在主目录中创建名为
go-on-azure
的新目录。mkdir ~/go-on-azure
切换到
go-on-azure
目录。cd ~/go-on-azure
运行
go mod init
以创建go.mod
文件。go mod init go-on-azure
运行
go get
以安装所需的 Go 模块。go get "github.com/Azure/azure-sdk-for-go/sdk/azidentity" go get "github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azsecrets"
创建一个名为
main.go
的文件,并添加以下代码。package main import ( "context" "fmt" "log" "os" "github.com/Azure/azure-sdk-for-go/sdk/azidentity" "github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azsecrets" ) func createSecret(name, value string) { keyVaultName := os.Getenv("KEY_VAULT_NAME") keyVaultUrl := fmt.Sprintf("https://%s.vault.azure.net/", keyVaultName) cred, err := azidentity.NewDefaultAzureCredential(nil) if err != nil { log.Fatalf("failed to obtain a credential: %v", err) } client, err := azsecrets.NewClient(keyVaultUrl, cred, nil) if err != nil { log.Fatalf("failed to create a client: %v", err) } params := azsecrets.SetSecretParameters{Value: &value} resp, err := client.SetSecret(context.TODO(), name, params, nil) if err != nil { log.Fatalf("failed to create a secret: %v", err) } fmt.Printf("Name: %s, Value: %s\n", *resp.ID, *resp.Value) } func main() { createSecret("ExamplePassword", "hVFkk965BuUv") }
创建一个名为
KEY_VAULT_NAME
的环境变量。 将环境变量值设置为之前创建的 Azure 密钥保管库的名称。export KEY_VAULT_NAME=<keyVaultName>
替换为
<keyVaultName>
Azure 密钥库 实例的名称。go run
运行命令以创建新的密钥保管库机密。go run main.go
成功后,输出类似于以下内容:
Name: https://<keyVaultName>.vault.azure.net/secrets/ExamplePassword/1e697f71d0014761a65641226f2f057b, Value: hVFkk965BuUv
5.清理资源
如果不想再使用本文中创建的 Azure 资源,最好将其删除。 删除未使用的资源有助于避免产生持续费用,并使订阅保持整洁。 删除本教程中使用的资源的最简单方法是删除资源组。
az group delete --name go-on-azure --yes
该 --yes
参数告知命令不要要求确认。
上述命令对资源组中的密钥保管库执行 软删除 。 若要永久将其从订阅中删除,请输入以下命令:
az keyvault purge --name <keyVaultName> --no-wait
将 <keyVaultName>
替换为你的密钥保管库名称。
最后,应删除应用注册和服务主体。
az ad app delete --id <servicePrincipalAppId>
替换为 <servicePrincipalAppId>
服务主体的应用 ID。