教程:使用托管标识将 Key Vault 连接到 .NET Azure Web 应用Tutorial: Use a managed identity to connect Key Vault to an Azure Web App with .NET

虽然 Azure Key Vault 提供安全存储凭据及其他机密的方式,但代码需要对 Key Vault 进行身份验证才能检索这些凭据和机密。Azure Key Vault provides a way to securely store credentials and other secrets, but your code needs to authenticate to Key Vault to retrieve them. Azure 资源的托管标识概述可帮助你解决此问题,其中介绍了如何在 Azure AD 中为 Azure 服务提供自动托管的标识。Managed identities for Azure resources overview helps to solve this problem by giving Azure services an automatically managed identity in Azure AD. 此标识可用于通过支持 Azure AD 身份验证的任何服务(包括 Key Vault)的身份验证,这样就无需在代码中插入任何凭据了。You can use this identity to authenticate to any service that supports Azure AD authentication, including Key Vault, without having to display credentials in your code.

本教程使用托管标识将 Azure Web 应用向 Azure Key Vault 进行身份验证。This tutorial uses a managed identity to authenticate an Azure Web App with an Azure Key Vault. 尽管这些步骤使用适用于 .NET 的 Azure Key Vault v4 客户端库Azure CLI,但在使用你选择的开发语言、Azure PowerShell 和/或 Azure 门户时,相同的基本原则也适用。Although the steps use the Azure Key Vault v4 client library for .NET and the Azure CLI, the same basic principles apply when using the development language of your choice, Azure PowerShell, and/or the Azure portal.

先决条件Prerequisites

若要完成本快速入门教程,需先执行以下操作:To complete this quickstart:

创建资源组Create a resource group

资源组是在其中部署和管理 Azure 资源的逻辑容器。A resource group is a logical container into which Azure resources are deployed and managed. 使用 az group create 命令创建一个资源组,用于存放密钥保管库和 Web 应用:Create a resource group to house both your key vault and your web app with the az group create command:

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

设置密钥保管库Set up your key vault

现在,你将创建一个密钥保管库,并在其中放置机密,以便在本教程的后面部分使用。You will now create a key vault and place a secret in it, for use later in this tutorial.

若要创建密钥保管库,请使用 az keyvault create 命令:To create a key vault, use the az keyvault create command:

重要

每个密钥保管库必须具有唯一的名称。Each key vault must have a unique name. 将以下示例中的 替换为你的密钥保管库名称。Replace with the name of your key vault in the following examples.

az keyvault create --name "<your-keyvault-name>" -g "myResourceGroup"

记下返回的 vaultUri(其格式将为“https://.vault.azure.cn/”)。Make a note of the returned vaultUri, which will be in the format"https://.vault.azure.cn/". 它将在更新代码步骤中使用。It will be used in the Update the code step.

现在可以使用 az keyvault secret set 命令将机密放入密钥保管库中。You can now place a secret in your key vault with the az keyvault secret set command. 将机密名称设置为“MySecret”,将值设置为 "Success!"。Set the name of your secret to "MySecret" and the value to "Success!".

az keyvault secret set --vault-name "<your-keyvault-name>" --name "MySecret" --value "Success!"

创建 .NET Web 应用Create a .NET web app

创建本地应用Create a local app

在计算机的终端窗口中,创建一个名为 akvwebapp 的目录,并将当前目录切换到该目录。In a terminal window on your machine, create a directory named akvwebapp and change the current directory to it.

mkdir akvwebapp
cd akvwebapp

现在,使用 dotnet new web 命令创建新的 .NET Core 应用程序:Now create a new .NET Core app with the dotnet new web command:

dotnet new web

在本地运行应用程序,以便你能了解将它部署到 Azure 时它的外观应该是什么样的。Run the application locally so that you see how it should look when you deploy it to Azure.

dotnet run

打开 Web 浏览器并导航到 http://localhost:5000 处的应用。Open a web browser, and navigate to the app at http://localhost:5000.

页面中会显示该示例应用发出的 Hello World 消息。You will see the Hello World message from the sample app displayed in the page.

初始化 Git 存储库Initialize the Git repository

在终端窗口中,按 Ctrl+C 退出 Web 服务器。In your terminal window, press Ctrl+C to exit the web server. 为 .NET Core 项目初始化 Git 存储库。Initialize a Git repository for the .NET Core project.

git init
git add .
git commit -m "first commit"

配置部署用户Configure a deployment user

可以使用“deployment user”将 FTP 和本地 Git 部署到 Azure Web 应用。FTP and local Git can deploy to an Azure web app by using a deployment user. 配置部署用户之后,可对所有 Azure 部署使用此用户。Once you configure your deployment user, you can use it for all your Azure deployments. 帐户级部署用户名和密码不同于 Azure 订阅凭据。Your account-level deployment username and password are different from your Azure subscription credentials.

若要配置部署用户,请运行 az webapp deployment user set 命令。To configure the deployment user, run the az webapp deployment user set command. 选择符合以下准则的用户名和密码:Choose a username and password that adheres to these guidelines:

  • 用户名在 Azure 中必须唯一,并且为了本地Git推送,不能包含“@”符号。The username must be unique within Azure, and for local Git pushes, must not contain the ‘@’ symbol.
  • 密码必须至少为 8 个字符,且具有字母、数字和符号这三种元素中的两种。The password must be at least eight characters long, with two of the following three elements: letters, numbers, and symbols.
az webapp deployment user set --user-name "<username>" --password "<password>"

JSON 输出会将该密码显示为 nullThe JSON output shows the password as null. 如果收到 'Conflict'. Details: 409 错误,请更改用户名。If you get a 'Conflict'. Details: 409 error, change the username. 如果收到 'Bad Request'. Details: 400 错误,请使用更强的密码。If you get a 'Bad Request'. Details: 400 error, use a stronger password.

请记录你要用于部署 Web 应用的用户名和密码。Record your username and password to use to deploy your web apps.

创建应用服务计划Create an app service plan

使用 Azure CLI az appservice plan create 命令创建应用服务计划。Create an App Service plan with the Azure CLI az appservice plan create command. 以下示例在“免费”定价层中创建名为 myAppServicePlan 的应用服务计划:This following example creates an App Service plan named myAppServicePlan in the Free pricing tier:

az appservice plan create --name myAppServicePlan --resource-group myResourceGroup --sku FREE

创建应用服务计划后,Azure CLI 将显示类似于以下示例的信息:When the App Service plan has been created, the Azure CLI shows information similar to the following example:

{ 
  "adminSiteName": null,
  "appServicePlanName": "myAppServicePlan",
  "geoRegion": "China East 2",
  "hostingEnvironmentProfile": null,
  "id": "/subscriptions/0000-0000/resourceGroups/myResourceGroup/providers/Microsoft.Web/serverfarms/myAppServicePlan",
  "kind": "app",
  "location": "China East 2",
  "maximumNumberOfWorkers": 1,
  "name": "myAppServicePlan",
  < JSON data removed for brevity. >
  "targetWorkerSizeId": 0,
  "type": "Microsoft.Web/serverfarms",
  "workerTierName": null
} 

创建远程 Web 应用Create a remote web app

myAppServicePlan 应用服务计划中创建 Azure Web 应用。Create an Azure web app in the myAppServicePlan App Service plan.

重要

与密钥保管库类似,Azure Web 应用必须具有独一无二的名称。Similar to Key Vault, an Azure Web App must have a unique name. 在以下示例中,请将 <your-webapp-name> 替换为 Web 应用的名称。Replace <your-webapp-name> with the name of your web app the following examples.

az webapp create --resource-group "myResourceGroup" --plan "myAppServicePlan" --name "<your-webapp-name>" --deployment-local-git

创建 Web 应用后,Azure CLI 会显示类似于以下示例的输出:When the web app has been created, the Azure CLI shows output similar to the following example:

Local git is configured with url of 'https://<username>@<your-webapp-name>.scm.chinacloudsites.cn/<ayour-webapp-name>.git'
{
  "availabilityState": "Normal",
  "clientAffinityEnabled": true,
  "clientCertEnabled": false,
  "clientCertExclusionPaths": null,
  "cloningInfo": null,
  "containerSize": 0,
  "dailyMemoryTimeQuota": 0,
  "defaultHostName": "<your-webapp-name>.chinacloudsites.cn",
  "deploymentLocalGitUrl": "https://<username>@<your-webapp-name>.scm.chinacloudsites.cn/<your-webapp-name>.git",
  "enabled": true,
  < JSON data removed for brevity. >
}

Git 远程的 URL 将显示在 deploymentLocalGitUrl 属性中,其格式为 https://<username>@<your-webapp-name>.scm.chinacloudsites.cn/<your-webapp-name>.gitThe URL of the Git remote is shown in the deploymentLocalGitUrl property, with the format https://<username>@<your-webapp-name>.scm.chinacloudsites.cn/<your-webapp-name>.git. 保存此 URL,因为稍后会需要它。Save this URL, as you need it later.

浏览到新建的应用。Browse to your newly created app. 将 <your-webapp-name> 替换为你的应用名称。Replace <your-webapp-name> with your app name.

https://<your-webapp-name>.chinacloudsites.cn

你将看到新创建的 Azure Web 应用的默认网页。You will see the default webpage for a newly created Azure Web App.

部署本地应用Deploy your local app

回到本地终端窗口,将 Azure 远程库添加到本地 Git 存储库,将 <deploymentLocalGitUrl-from-create-step> 替换为在创建远程 Web 应用步骤中保存的 Git 远程库的 URL。Back in the local terminal window, add an Azure remote to your local Git repository, replacing <deploymentLocalGitUrl-from-create-step> with the URL of the Git remote that you saved from Create a remote web app step.

git remote add azure <deploymentLocalGitUrl-from-create-step>

使用以下命令推送到 Azure 远程库以部署应用。Push to the Azure remote to deploy your app with the following command. 当 Git 凭据管理器提示你输入凭据时,请使用你在配置部署用户步骤中创建的凭据。When Git Credential Manager prompts you for credentials, use the credentials you created in Configure a deployment user step.

git push azure master

此命令可能需要花费几分钟时间运行。This command may take a few minutes to run. 运行时,该命令会显示类似于以下示例的信息:While running, it displays information similar to the following example:

Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 285 bytes | 95.00 KiB/s, done.
Total 3 (delta 2), reused 0 (delta 0), pack-reused 0
remote: Deploy Async
remote: Updating branch 'master'.
remote: Updating submodules.
remote: Preparing deployment for commit id 'd6b54472f7'.
remote: Repository path is /home/site/repository
remote: Running oryx build...
remote: Build orchestrated by Microsoft Oryx, https://github.com/Microsoft/Oryx
remote: You can report issues at https://github.com/Microsoft/Oryx/issues
remote:
remote: Oryx Version      : 0.2.20200114.13, Commit: 204922f30f8e8d41f5241b8c218425ef89106d1d, ReleaseTagName: 20200114.13
remote: Build Operation ID: |imoMY2y77/s=.40ca2a87_
remote: Repository Commit : d6b54472f7e8e9fd885ffafaa64522e74cf370e1
.
.
.
remote: Deployment successful.
remote: Deployment Logs : 'https://<your-webapp-name>.scm.chinacloudsites.cn/newui/jsonviewer?view_url=/api/deployments/d6b54472f7e8e9fd885ffafaa64522e74cf370e1/log'
To https://<your-webapp-name>.scm.chinacloudsites.cn:443/<your-webapp-name>.git
   d87e6ca..d6b5447  master -> master

使用 Web 浏览器浏览到(或刷新)已部署的应用程序。Browse to (or refresh) the deployed application using your web browser.

http://<your-webapp-name>.chinacloudsites.cn

此时会显示“Hello World!”You will see the "Hello World!" 消息,你以前在访问 http://localhost:5000 时看到过该消息。message you previously saw when visiting http://localhost:5000.

创建并分配托管标识Create and assign a managed identity

在 Azure CLI 中,若要为此应用程序创建标识,请运行 az webapp-identity assign 命令:In the Azure CLI, to create the identity for this application, run the az webapp-identity assign command:

az webapp identity assign --name "<your-webapp-name>" --resource-group "myResourceGroup"

该操作将返回此 JSON 代码片段:The operation will return this JSON snippet:

{
  "principalId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "tenantId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "type": "SystemAssigned"
}

若要为 Web 应用授予在密钥保管库上执行 getlist 的权限,请将 principalID 传递到 Azure CLI az keyvault set-policy 命令:To give your web app permission to do get and list operations on your key vault, pass the principalID to the Azure CLI az keyvault set-policy command:

az keyvault set-policy --name "<your-keyvault-name>" --object-id "<principalId>" --secret-permissions get list

修改应用以访问密钥保管库Modify the app to access your key vault

安装包Install the packages

在终端窗口中,安装适用于 .NET 的 Azure Key Vault 客户端库包:From the terminal window, install the Azure Key Vault client library for .NET packages:

dotnet add package Azure.Identity
dotnet add package Azure.Security.KeyVault.Secrets

更新代码Update the code

在 akvwebapp 项目中找到 Startup.cs 文件并将其打开。Find and open the Startup.cs file in your akvwebapp project.

在该文件头部添加以下两行:Add these two lines to the header:

using Azure.Identity;
using Azure.Security.KeyVault.Secrets;

将以下行添加到 app.UseEndpoints 调用之前,更新 URI 以反映密钥保管库的 vaultUriAdd these lines before the app.UseEndpoints call, updating the URI to reflect the vaultUri of your key vault. 下面的代码将 DefaultAzureCredential() 用于向密钥保管库进行身份验证,该类使用来自应用程序托管标识的令牌进行身份验证。Below code is using 'DefaultAzureCredential()' for authentication to key vault, which is using token from application managed identity to authenticate. 它还在密钥保管库受到限制的情况下将指数退避用于重试。It is also using exponential backoff for retries in case of key vault is being throttled.

SecretClientOptions options = new SecretClientOptions()
    {
        Retry =
        {
            Delay= TimeSpan.FromSeconds(2),
            MaxDelay = TimeSpan.FromSeconds(16),
            MaxRetries = 5,
            Mode = RetryMode.Exponential
         }
    };
var client = new SecretClient(new Uri("https://<your-unique-key-vault-name>.vault.azure.cn/"), new DefaultAzureCredential(),options);

KeyVaultSecret secret = client.GetSecret("mySecret");

string secretValue = secret.Value;

await context.Response.WriteAsync("Hello World!"); 行更新为:Update the line await context.Response.WriteAsync("Hello World!"); to read:

await context.Response.WriteAsync(secretValue);

请确保在继续下一步之前保存更改。Be certain to save your changes before proceeding to the next step.

重新部署 Web 应用Redeploy your web app

更新代码后,可以使用以下 Git 命令将其重新部署到 Azure:Having updated your code, you can redeploy it to Azure with the following Git commands:

git add .
git commit -m "Updated web app to access my key vault"
git push azure master

访问已完成的 Web 应用Visit your completed web app

http://<your-webapp-name>.chinacloudsites.cn

在以前显示 Hello World 的地方,现在应显示机密值:成功!Where before you saw Hello World, you should now see the value of your secret displayed: Success!

后续步骤Next steps