你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

快速入门:适用于 Go 的 Azure Key Vault 证书客户端库

在本快速入门中,你将了解如何使用 Azure SDK for Go 在 Azure Key Vault 中管理证书。

Azure Key Vault 是一项云服务,用作安全的机密存储。 可以安全地存储密钥、密码、证书和其他机密。 有关 Key Vault 的详细信息,可以参阅概述

按照此指南操作,了解如何通过 Go 使用 azcertificates 包来管理 Azure Key Vault 证书。

先决条件

登录到 Azure 门户

  1. 在 Azure CLI 中运行以下命令:

    az login
    

    如果 Azure CLI 可以打开默认浏览器,它将在默认浏览器中打开 Azure 门户登录页。

    如果此页面没有自动打开,请转到 https://aka.ms/devicelogin,然后输入在你的终端中显示的授权代码。

  2. 使用你的帐户凭据登录到 Azure 门户。

创建资源组和 Key Vault

本快速入门使用预先创建的 Azure 密钥保管库。 可以遵循 Azure CLI 快速入门Azure PowerShell 快速入门Azure 门户快速入门中的步骤创建 Key Vault。

或者,也可运行这些 Azure CLI 或 Azure PowerShell 命令。

重要

每个密钥保管库必须具有唯一的名称。 在以下示例中,将 <your-unique-keyvault-name> 替换为密钥保管库的名称。

az group create --name "myResourceGroup" -l "EastUS"

az keyvault create --name "<your-unique-keyvault-name>" -g "myResourceGroup" --enable-rbac-authorization

授予对 Key Vault 的访问权限

若要通过基于角色的访问控制 (RBAC) 授予对密钥保管库的权限,请使用 Azure CLI 命令 az role assignment create 将角色分配给你的“用户主体名称”(UPN)。

az role assignment create --role "Key Vault Certificate Officer" --assignee "<upn>" --scope "/subscriptions/<subscription-id>/resourceGroups/<resource-group-name>/providers/Microsoft.KeyVault/vaults/<your-unique-keyvault-name>"

将 <upn>、<subscription-id>、<resource-group-name> 和 <your-unique-keyvault-name> 替换为你的实际值。 你的 UPN 通常采用电子邮件地址格式(例如 username@domain.com)。

创建新的 Go 模块并安装包

运行以下 Go 命令:

go mod init quickstart-go-kvcerts
go get github.com/Azure/azure-sdk-for-go/sdk/keyvault/azcertificates
go get github.com/Azure/azure-sdk-for-go/sdk/azidentity

创建示例代码

创建名为 main.go 的文件并将以下代码复制到该文件中:

package main

import (
	"context"
	"fmt"
	"log"
	"time"

	"github.com/Azure/azure-sdk-for-go/sdk/azcore/to"
	"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
	"github.com/Azure/azure-sdk-for-go/sdk/keyvault/azcertificates"
)

func getClient() *azcertificates.Client {
	keyVaultName := os.Getenv("KEY_VAULT_NAME")
	if keyVaultName == "" {
		log.Fatal("KEY_VAULT_NAME environment variable not set")
	}
	keyVaultUrl := fmt.Sprintf("https://%s.vault.azure.net/", keyVaultName)

	cred, err := azidentity.NewDefaultAzureCredential(nil)
	if err != nil {
		log.Fatal(err)
	}

	return azcertificates.NewClient(keyVaultUrl, cred, nil)
}

func createCert(client *azcertificates.Client) {
	params := azcertificates.CreateCertificateParameters{
		CertificatePolicy: &azcertificates.CertificatePolicy{
			IssuerParameters: &azcertificates.IssuerParameters{
				Name: to.Ptr("Self"),
			},
			X509CertificateProperties: &azcertificates.X509CertificateProperties{
				Subject: to.Ptr("CN=DefaultPolicy"),
			},
		},
	}
	resp, err := client.CreateCertificate(context.TODO(), "myCertName", params, nil)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("Requested a new certificate. Operation status: %s\n", *resp.Status)
}

func getCert(client *azcertificates.Client) {
	// an empty string version gets the latest version of the certificate
	version := ""
	getResp, err := client.GetCertificate(context.TODO(), "myCertName", version, nil)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("Enabled set to:", *getResp.Attributes.Enabled)
}

func listCert(client *azcertificates.Client) {
	pager := client.NewListCertificatesPager(nil)
	for pager.More() {
		page, err := pager.NextPage(context.Background())
		if err != nil {
			log.Fatal(err)
		}
		for _, cert := range page.Value {
			fmt.Println(*cert.ID)
		}
	}
}

func updateCert(client *azcertificates.Client) {
	// disables the certificate, sets an expires date, and add a tag
	params := azcertificates.UpdateCertificateParameters{
		CertificateAttributes: &azcertificates.CertificateAttributes{
			Enabled: to.Ptr(false),
			Expires: to.Ptr(time.Now().Add(72 * time.Hour)),
		},
		Tags: map[string]*string{"Owner": to.Ptr("SRE")},
	}
	// an empty string version updates the latest version of the certificate
	version := ""
	_, err := client.UpdateCertificate(context.TODO(), "myCertName", version, params, nil)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("Updated certificate properites: Enabled=false, Expires=72h, Tags=SRE")
}

func deleteCert(client *azcertificates.Client) {
	// DeleteCertificate returns when Key Vault has begun deleting the certificate. That can take several
	// seconds to complete, so it may be necessary to wait before performing other operations on the
	// deleted certificate.
	resp, err := client.DeleteCertificate(context.TODO(), "myCertName", nil)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("Deleted certificate with ID: ", *resp.ID)
}

func main() {
	fmt.Println("Authenticating...")
	client := getClient()

	fmt.Println("Creating a certificate...")
	createCert(client)

	fmt.Println("Getting certificate Enabled property ...")
	getCert(client)

	fmt.Println("Listing certificates...")
	listCert(client)

	fmt.Println("Updating a certificate...")
	updateCert(client)

	fmt.Println("Deleting a certificate...")
	deleteCert(client)
}

运行代码

在运行代码前,请创建名为 KEY_VAULT_NAME 的环境变量。 将环境变量值设置为之前创建的 Azure 密钥保管库的名称。

export KEY_VAULT_NAME=<YourKeyVaultName>

接下来,运行以下 go run 命令来运行应用:

go run main.go

代码示例

有关更多示例,请参阅模块文档

清理资源

运行以下命令来删除资源组及其所有剩余资源:

az group delete --resource-group myResourceGroup

后续步骤