チュートリアル:マネージド ID を使用して Key Vault を .NET の Azure Web アプリに接続する

Azure Key Vault は、資格情報やその他のシークレットをより安全に格納する方法を提供します。 ただし、それらを取得するためには、コードから Key Vault に対する認証を行う必要があります。 Azure リソースのマネージド ID に関するページは、Microsoft Entra ID で自動的に管理される ID を Azure サービスに提供することで、この問題を解決するのに役立ちます。 この ID を使用して、コードに資格情報が表示されていなくても、Key Vault を含む Microsoft Entra の認証をサポートする任意のサービスに認証することができます。

このチュートリアルでは、Azure Web アプリケーションを作成して Azure App Service にデプロイします。 マネージド ID、Azure key vault、.NET 用の Azure Key Vault シークレット クライアント ライブラリAzure CLI を使って Azure Web アプリを認証します。 各種の開発言語や Azure PowerShell、Azure portal を使用する場合でも、基本的な原則は同じです。

このチュートリアルで紹介する Azure App Service Web アプリケーションとデプロイの詳細については、以下を参照してください。

[前提条件]

このチュートリアルを完了するには、次のものが必要です。

既に Web アプリケーションを Azure App Service にデプロイしている場合は、キー コンテナーへの Web アプリ アクセスの構成に関するセクションおよび Web アプリケーション コードの変更に関するセクションにスキップできます。

.NET Core アプリを作成する

この手順では、ローカル .NET Core プロジェクトを設定します。

マシンのターミナル ウィンドウで、akvwebapp という名前のディレクトリを作成し、現在のディレクトリをそのディレクトリに変更します。

mkdir akvwebapp
cd akvwebapp

dotnet new web コマンドを使用して .NET Core アプリを作成します。

dotnet new web

アプリケーションをローカルで実行すると、アプリケーションを Azure にデプロイしたときにどう表示されるかを把握できます。

dotnet run

Web ブラウザーでアプリ (http://localhost:5000) に移動します。

サンプル アプリの “Hello World!” メッセージがページに表示されます。

Azure 用に Web アプリケーションを作成する方法の詳細については、Azure App Service での ASP.NET Core Web アプリの作成に関するページを参照してください。

Azure にアプリケーションをデプロイする

この手順では、ローカル Git を使用して、Azure App Service に .NET Core アプリケーションをデプロイします。 アプリケーションを作成してデプロイする方法について詳しくは、Azure に ASP.NET Core Web アプリを作成する方法に関するページを参照してください。

ローカル Git デプロイを構成する

ターミナル ウィンドウで Ctrl + C キーを押して Web サーバーを閉じます。 次のコマンドを実行して、.NET Core プロジェクト用の Git リポジトリを初期化してください。

git init --initial-branch=main
git add .
git commit -m "first commit"

FTP およびローカルの Git を使用し、"デプロイ ユーザー" を使用して Azure Web アプリをデプロイできます。 デプロイ ユーザーを構成すると、すべての Azure デプロイでこのユーザーを使用できます。 アカウントレベルのデプロイのユーザー名とパスワードは、Azure サブスクリプションの資格情報とは異なります。

デプロイ ユーザーを構成するには、az webapp deployment user set コマンドを実行します。 次のガイドラインに準拠したユーザー名とパスワードを選択してください。

  • ユーザー名は Azure 内で一意になっている必要があります。 ローカルの Git プッシュでは、アット マーク (@) を含めることはできません。
  • パスワードは長さが 8 文字以上で、文字、数字、記号のうち 2 つを含む必要があります。
az webapp deployment user set --user-name "<username>" --password "<password>"

JSON 出力には、パスワードが null として表示されます。 'Conflict'. Details: 409 エラーが発生した場合は、ユーザー名を変更します。 'Bad Request'. Details: 400 エラーが発生した場合は、より強力なパスワードを使用します。

Web アプリのデプロイに使用できるよう、ユーザー名とパスワードを記録してください。

リソース グループを作成する

リソース グループは、Azure リソースをデプロイして管理するための入れ物となる論理コンテナーです。 キー コンテナーと Web アプリの配置先となるリソース グループは、az group create コマンドを使用して作成します。

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

App Service プランを作成する

Azure CLI の az appservice plan create コマンドを使用して、App Service プランを作成します。 次の例では、FREE 価格レベルの myAppServicePlan という名前の App Service プランを作成します。

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

App Service プランが作成されると、Azure CLI によって、次のような情報が表示されます。

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

詳細については、「Azure で App Service プランを管理する」を参照してください。

Web アプリを作成する

myAppServicePlan App Service プランに Azure Web アプリを作成します。

重要

キー コンテナーと同様、Azure Web アプリにも一意の名前を付ける必要があります。 次の例の <your-webapp-name> は、実際の Web アプリの名前に置き換えてください。

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

Web アプリが作成されると、Azure CLI によって次のような出力が表示されます。

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

Git リモートの URL は deploymentLocalGitUrl プロパティに https://<username>@<your-webapp-name>.scm.azurewebsites.net/<your-webapp-name>.git 形式で出力されます。 この URL を保存します。 この情報は後で必要になります。

次に、main ブランチからデプロイするように Web アプリを構成します。

 az webapp config appsettings set -g MyResourceGroup --name "<your-webapp-name>" --settings deployment_branch=main

次のコマンドを使用して新しいアプリに移動します。 <your-webapp-name> は、実際のアプリの名前に置き換えてください。

https://<your-webapp-name>.azurewebsites.net

新しい Azure Web アプリの既定の Web ページが表示されます。

ローカル アプリをデプロイする

ローカル ターミナル ウィンドウで、ローカル Git リポジトリに Azure リモートを追加します。 次のコマンドの <deploymentLocalGitUrl-from-create-step> は、「Web アプリを作成する」セクションで保存した Git リモートの URL に置き換えてください。

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

Azure リモートにアプリをプッシュしてデプロイするには、以下のコマンドを使用します。 Git Credential Manager によって資格情報の入力を求めるメッセージが表示されたら、「ローカル Git デプロイを構成する」セクションで作成した資格情報を使用してください。

git push azure main

このコマンドの実行には数分かかることがあります。 実行中、次のような情報が表示されます。

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 'main'.
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.azurewebsites.net/newui/jsonviewer?view_url=/api/deployments/d6b54472f7e8e9fd885ffafaa64522e74cf370e1/log'
To https://<your-webapp-name>.scm.azurewebsites.net:443/<your-webapp-name>.git
   d87e6ca..d6b5447  main -> main

デプロイされたアプリケーションに移動 (または最新の情報に更新) します。

http://<your-webapp-name>.azurewebsites.net

http://localhost:5000 にアクセスすると、先ほどの “Hello World” メッセージが表示されます。

Git を使用した Web アプリケーションのデプロイの詳細については、「Azure App Service へのローカル Git デプロイ」を参照してください

Key Vault に接続するように Web アプリを構成する

このセクションでは、Key Vault への Web アクセスを構成し、Key Vault からシークレットを取得するようにアプリケーション コードを更新します。

マネージド ID を作成して割り当てる

このチュートリアルでは、マネージド ID を使用して Key Vault に対する認証を行います。 マネージド ID によって自動的にアプリケーションの資格情報が管理されます。

このアプリケーションの ID を作成するために、Azure CLI で az webapp-identity assign コマンドを実行します。

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

このコマンドからは、次の JSON スニペットが返されます。

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

キー コンテナーに対する get 操作と list 操作のアクセス許可を Web アプリに与えるため、Azure CLI の az keyvault set-policy コマンドに principalId を渡します。

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

Azure portal または PowerShell を使用してアクセス ポリシーを割り当てることもできます。

キー コンテナーにアクセスするようアプリを変更する

このチュートリアルでは、デモンストレーションとして Azure Key Vault シークレット クライアント ライブラリを使用します。 Azure Key Vault 証明書クライアント ライブラリAzure Key Vault キー クライアント ライブラリを使用することもできます。

パッケージのインストール

ターミナル ウィンドウから、.NET 用 Azure Key Vault シークレット クライアント ライブラリ パッケージと Azure ID クライアント ライブラリ パッケージをインストールします。

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

コードを更新する

akvwebapp プロジェクトで、.NET 5.0 以前には Startup.cs ファイルを、.NET 6.0 には Program.cs ファイルを見つけて開きます。

次の行をヘッダーに追加します。

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

(.NET 5.0 以前の場合) app.UseEndpoints 呼び出しの前に、(.NET 6.0 の場合) app.MapGet 呼び出しの前に以下の行を追加します。URI は、実際のキー コンテナーの vaultUri に合わせて更新してください。 このコードでは DefaultAzureCredential() を使って Key Vault に対する認証を行います。Key Vault では、マネージド ID から受け取るトークンを使って認証を行います。 Key Vault に対する認証の詳細については、開発者ガイドを参照してください。 また、このコードでは、Key Vault がスロットルされている場合の再試行にはエクスポネンシャル バックオフが使用されています。 Key Vault のトランザクション制限について詳しくは、「Azure Key Vault のスロットル ガイダンス」を参照してください。

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.net/"), new DefaultAzureCredential(),options);

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

string secretValue = secret.Value;
.NET 5.0 以前

await context.Response.WriteAsync("Hello World!"); という行を次のように更新します。

await context.Response.WriteAsync(secretValue);
.NET 6.0

app.MapGet("/", () => "Hello World!"); という行を次のように更新します。

app.MapGet("/", () => secretValue);

次の手順に進む前に、必ず変更内容を保存してください。

Web アプリを再デプロイする

コードを更新したら、次の Git コマンドを使用して、そのコードを Azure に再デプロイすることができます。

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

完成した Web アプリにアクセスする

http://<your-webapp-name>.azurewebsites.net

"Hello World!" が表示される前に、シークレットの値が表示されるはずです。

次の手順