教程:将 Azure Key Vault 与通过 .NET 编写的 Windows 虚拟机配合使用Tutorial: Use Azure Key Vault with a Windows virtual machine in .NET

Azure Key Vault 用于保护机密,例如访问应用程序、服务和 IT 资源所需的 API 密钥、数据库连接字符串。Azure Key Vault helps you to protect secrets such as API keys, the database connection strings you need to access your applications, services, and IT resources.

本教程介绍如何获取控制台应用程序,以便从 Azure Key Vault 读取信息。In this tutorial, you learn how to get a console application to read information from Azure Key Vault. 为此,请将托管标识用于 Azure 资源。To do so, you use managed identities for Azure resources.

本教程介绍如何:The tutorial shows you how to:

  • 创建资源组。Create a resource group.
  • 创建密钥保管库。Create a key vault.
  • 将机密添加到 Key Vault。Add a secret to the key vault.
  • 从密钥保管库检索机密。Retrieve a secret from the key vault.
  • 创建一个 Azure 虚拟机。Create an Azure virtual machine.
  • 为虚拟机启用托管标识Enable a managed identity for the Virtual Machine.
  • 为 VM 标识分配权限。Assign permissions to the VM identity.

在开始之前,请阅读 Key Vault 的基本概念Before you begin, read Key Vault basic concepts.

如果没有 Azure 订阅,请创建一个试用帐户If you don’t have an Azure subscription, create a trial account.

先决条件Prerequisites

对于 Windows、Mac 和 Linux:For Windows, Mac, and Linux:

  • GitGit
  • 本教程要求在本地运行 Azure CLI。This tutorial requires that you run the Azure CLI locally. 必须安装 Azure CLI 2.0.4 或更高版本。You must have the Azure CLI version 2.0.4 or later installed. 运行 az --version 即可查找版本。Run az --version to find the version. 如果需要安装或升级 CLI,请参阅安装 Azure CLI 2.0If you need to install or upgrade the CLI, see Install Azure CLI 2.0.

关于托管服务标识About Managed Service Identity

Azure Key Vault 可以安全地存储凭据,因此不需要在代码中显示凭据。Azure Key Vault stores credentials securely, so they're not displayed in your code. 但是,需要对 Azure Key Vault 进行身份验证才能检索密钥。However, you need to authenticate to Azure Key Vault to retrieve your keys. 若要对 Key Vault 进行身份验证,需要提供凭据。To authenticate to Key Vault, you need a credential. 因此,在启动过程中,这是一个难以兼顾的典型问题。It's a classic bootstrap dilemma. 托管服务标识 (MSI) 提供简化该过程的启动标识,可以解决此问题。 Managed Service Identity (MSI) solves this issue by providing a bootstrap identity that simplifies the process.

为 Azure 服务(例如 Azure 虚拟机、Azure 应用服务或 Azure Functions)启用 MSI 时,Azure 会创建一个服务主体When you enable MSI for an Azure service, such as Azure Virtual Machines, Azure App Service, or Azure Functions, Azure creates a service principal. MSI 针对 Azure Active Directory (Azure AD) 中的服务实例提供启动标识,并将服务主体凭据注入该实例。MSI does this for the instance of the service in Azure Active Directory (Azure AD) and injects the service principal credentials into that instance.

MSI

接下来,为了获取访问令牌,代码会调用 Azure 资源上提供的本地元数据服务。Next, to get an access token, your code calls a local metadata service that's available on the Azure resource. 代码使用从本地 MSI 终结点获取的访问令牌,以便向 Azure Key Vault 服务进行身份验证。To authenticate to an Azure Key Vault service, your code uses the access token that it gets from the local MSI endpoint.

创建资源并分配权限Create resources and assign permissions

在开始编码之前,需要创建一些资源,将机密放入密钥保管库中,并分配权限。Before you start coding you need to create some resources, put a secret into your key vault, and assign permissions.

登录 AzureSign in to Azure

若要使用 Azure CLI 登录到 Azure,请输入:To sign in to Azure by using the Azure CLI, enter:

az cloud set –n  AzureChinaCloud 
az login

创建资源组Create a resource group

Azure 资源组是在其中部署和管理 Azure 资源的逻辑容器。An Azure resource group is a logical container into which Azure resources are deployed and managed. 使用 az group create 命令创建资源组。Create a resource group by using the az group create command.

此示例在“中国东部”位置创建资源组:This example creates a resource group in the China East location:

# To list locations: az account list-locations --output table
az group create --name "<YourResourceGroupName>" --location "China North"

新建的资源组将在本教程中使用。Your newly created resource group will be used throughout this tutorial.

创建密钥保管库并使用机密填充它Create a key vault and populate it with a secret

通过提供带有以下信息的 az keyvault create 命令,在资源组中创建密钥保管库:Create a key vault in your resource group by providing the az keyvault create command with the following information:

  • Key Vault 名称:由 3 到 24 个字符构成的字符串,可以包含数字 (0-9)、字母 (a-z, A-Z) 和连字符 (-)Key vault name: a string of 3 to 24 characters that can contain only numbers (0-9), letters (a-z, A-Z), and hyphens (-)
  • 资源组名称Resource group name
  • 位置:中国北部Location: China North.
az keyvault create --name "<YourKeyVaultName>" --resource-group "<YourResourceGroupName>" --location "China North"

目前,只有你的 Azure 帐户才有权对这个新的 Key Vault 执行操作。At this point, your Azure account is the only one that's authorized to perform operations on this new key vault.

现在使用 az keyvault secret set 命令向密钥保管库中添加机密Now add a secret to your key vault using the az keyvault secret set command

若要在名为 AppSecret 的 Key Vault 中创建机密,请输入以下命令:To create a secret in the key vault called AppSecret, enter the following command:

az keyvault secret set --vault-name "<YourKeyVaultName>" --name "AppSecret" --value "MySecret"

此机密将存储值 MySecretThis secret stores the value MySecret.

创建虚拟机Create a virtual machine

使用以下方法之一创建虚拟机:Create a virtual machine by using one of the following methods:

为 VM 分配标识Assign an identity to the VM

使用 az vm identity assign 命令为虚拟机创建系统分配的标识:Create a system-assigned identity for the virtual machine with the az vm identity assign command:

az vm identity assign --name <NameOfYourVirtualMachine> --resource-group <YourResourceGroupName>

记下以下代码中显示的系统分配的标识。Note the system-assigned identity that's displayed in the following code. 以上命令的输出为:The output of the preceding command would be:

{
  "systemAssignedIdentity": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "userAssignedIdentities": {}
}

为 VM 标识分配权限Assign permissions to the VM identity

使用 az keyvault set-policy 命令将以前创建的标识权限分配给密钥保管库:Assign the previously created identity permissions to your key vault with the az keyvault set-policy command:

az keyvault set-policy --name '<YourKeyVaultName>' --object-id <VMSystemAssignedIdentity> --secret-permissions get list

登录到虚拟机Sign in to the virtual machine

若要登录到虚拟机,请按照连接并登录到运行 Windows 的 Azure 虚拟机中的说明操作。To sign in to the virtual machine, follow the instructions in Connect and sign in to an Azure virtual machine running Windows.

设置控制台应用Set up the console app

创建控制台应用,并使用 dotnet 命令安装所需的包。Create a console app and install the required packages using the dotnet command.

安装 .NET CoreInstall .NET Core

若要安装 .NET Core,请转到 .NET 下载页。To install .NET Core, go to the .NET downloads page.

创建并运行示例 .NET 应用Create and run a sample .NET app

打开命令提示符。Open a command prompt.

可以运行以下命令,将“Hello World”输出到控制台:You can print "Hello World" to the console by running the following commands:

dotnet new console -o helloworldapp
cd helloworldapp
dotnet run

安装包Install the packages

在控制台窗口中,安装本快速入门所需的 .NET 包:From the console window, install the .NET packages required for this quickstart:

dotnet add package System.IO;
dotnet add package System.Net;
dotnet add package System.Text;
dotnet add package Newtonsoft.Json;
dotnet add package Newtonsoft.Json.Linq;

编辑控制台应用Edit the console app

打开 Program.cs 文件并添加以下包:Open the Program.cs file and add these packages:

using System;
using System.IO;
using System.Net;
using System.Text;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

编辑类文件,使之包含在下面的三步过程中使用的代码:Edit the class file to contain the code in the following three-step process:

  1. 从 VM 上的本地 MSI 终结点获取一个令牌。Fetch a token from the local MSI endpoint on the VM. 这还会从 Azure AD 获取令牌。Doing so also fetches a token from Azure AD.
  2. 将令牌传递到 Key Vault,然后获取机密。Pass the token to your key vault, and then fetch your secret.
  3. 将保管库名称和机密名称添加到请求。Add the vault name and secret name to the request.
 class Program
    {
        static void Main(string[] args)
        {
            // Step 1: Get a token from the local (URI) Managed Service Identity endpoint, which in turn fetches it from Azure AD
            var token = GetToken();

            // Step 2: Fetch the secret value from your key vault
            System.Console.WriteLine(FetchSecretValueFromKeyVault(token));
        }

        static string GetToken()
        {
            WebRequest request = WebRequest.Create("https://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https%3A%2F%2Fvault.azure.cn");
            request.Headers.Add("Metadata", "true");
            WebResponse response = request.GetResponse();
            return ParseWebResponse(response, "access_token");
        }
        
        static string FetchSecretValueFromKeyVault(string token)
        {
            //Step 3: Add the vault name and secret name to the request.
            WebRequest kvRequest = WebRequest.Create("https://<YourVaultName>.vault.azure.cn/secrets/<YourSecretName>?api-version=2016-10-01");
            kvRequest.Headers.Add("Authorization", "Bearer "+  token);
            WebResponse kvResponse = kvRequest.GetResponse();
            return ParseWebResponse(kvResponse, "value");
        }

        private static string ParseWebResponse(WebResponse response, string tokenName)
        {
            string token = String.Empty;
            using (Stream stream = response.GetResponseStream())
            {
                StreamReader reader = new StreamReader(stream, Encoding.UTF8);
                String responseString = reader.ReadToEnd();

                JObject joResponse = JObject.Parse(responseString);    
                JValue ojObject = (JValue)joResponse[tokenName];             
                token = ojObject.Value.ToString();
            }
            return token;
        }
    }

以上代码演示了如何在 Windows 虚拟机中通过 Azure Key Vault 执行操作。The preceding code shows you how to do operations with Azure Key Vault in a Windows virtual machine.

清理资源Clean up resources

不再需要本教程中创建的虚拟机和 Key Vault 时,请将其删除。When they are no longer needed, delete the virtual machine and your key vault.

后续步骤Next steps