演習 - マネージド ID を使用して .NET でカスタム アプリケーションを構成する
アプリケーションの接続文字列、資格情報、パスワード、およびその他の機密情報を Azure Key Vault に格納することができます。 Key Vault にアクセスするには、資格情報を提供する必要があります。 Azure VM へのアプリケーション移行の一部として、マネージド ID を使用して、Key Vault に対して認証するアクセス トークンを取得するように更新できるようになりました。
在庫追跡アプリケーションは、Azure SQL Database に接続します。 以前、オンプレミスのアプリは、構成ファイルに接続文字列を保存していました。 Azure への移行の一環として、すべての資格情報と接続文字列が Azure Key Vault に安全に格納されるようになりました。
在庫追跡アプリケーションは仮想マシン (VM) 上で実行されるので、作成したシステム割り当てマネージド ID を使用できます。 キー コンテナーに、適切なアクセス許可を VM に付与するポリシーを追加します。
この演習では、新しいキー コンテナーを使用するようにアプリを編集します。 次に、アプリがデータベース接続を取得できるように、VM アクセスにマネージド ID を付与します。 最後に、VM でアプリをビルドして実行し、Key Vault にアクセスして情報を取得します。
Key Vault からシークレット情報をフェッチするアプリを作成する
先ほど作成した VM にサインインします。
ssh $publicIP
Note
環境変数
publicIP
が設定されていない場合は、次のコマンドを実行してリセットします。export publicIP=$(az vm show \ --name prodserver \ --resource-group "<rgn>[sandbox resource group name]</rgn>" \ --show-details \ --query [publicIps] \ --output tsv)
その後、
ssh $publicIP
コマンドを再実行します。identity/secretapp フォルダーに移動します。
cd ~/identity/secretapp
nano エディターを使って、Program.cs ファイルを開きます。
nano Program.cs
このファイルには、サンプル アプリの C# ソース コードが含まれています。
Main
メソッドを調べます。static async Task Main(string[] args) { await GetSecretFromKeyVault().ConfigureAwait(false); }
このメソッドは、
GetSecretFromKeyVault
メソッドを呼び出すだけのアプリケーションのエントリ ポイントです。GetSecretFromKeyVault
メソッドまで下に移動します。 メソッドの最初のコード ブロックを調べます。private static async Task GetSecretFromKeyVault() { var keyVaultName = "<key vault name>"; Uri keyVaultUri = new Uri($"https://{keyVaultName}.vault.azure.net"); SecretClient secretClient = new SecretClient(keyVaultUri, new DefaultAzureCredential()); ... }
"<key vault name>"
を自分のキー コンテナーの名前に置き換えます。 このコードでは、DefaultAzureCredential
を使用して、要求を行うクライアントを認証します。 このコードはバックグラウンドで、コードを実行する VM のシステム マネージド ID を取得します。 次に、この認証スキームを使用するSecretClient
のインスタンスを生成します。 このSecretClient
インスタンスを使用して、キー コンテナーのシークレットにアクセスできます。コードの次の部分を見てください。
var keyVaultSecretName = "<secret name>"; try { var secret = await secretClient.GetSecretAsync(keyVaultSecretName).ConfigureAwait(false); Console.WriteLine($"Secret: {secret.Value}"); } catch (Exception exp) { Console.WriteLine($"Something went wrong: {exp.Message}"); }
<secret name>
を"DBCredentials"
に置き換えます。これは、キー コンテナーで作成したシークレットの名前です。このコード ブロックは、
SecretClient
のGetSecretAsync
メソッドを呼び出して、特定のシークレットを取得し、その値を表示します。 キーにアクセスするためのアクセス許可がクライアントにない場合、このコードは例外をスローし、エラー メッセージを表示します。Note
パスワード、証明書、またはクライアント シークレットは、コードに格納されません。
変更を保存するには、Ctrl + O キーを押してから Enter キーを押します。
nano エディターを閉じるには、Ctrl + X キーを押します。
アプリケーションをテストする
次のコマンドを実行して、アプリケーションをビルドします。
dotnet restore dotnet build
プログラムを正しく編集した場合は、エラーが発生せずにアプリがビルドされるはずです。
アプリケーションを実行します。
dotnet run
キー コンテナーにアクセスするための VM のサービス プリンシパルをまだ承認していません。 したがって、アプリケーションは、次のエラー メッセージを表示して応答します。
Something went wrong: Operation returned an invalid status code 'Forbidden'
サービス プリンシパルが Key Vault からシークレットを取得できるようにするためにアクセス許可を付与する
VM への接続を閉じます。
exit
前の演習で、ご自分の VM のプリンシパル ID をメモしました。 プリンシパル ID を覚えていない場合は、次のコマンドを実行して、VM のシステム割り当て ID を検索します。 (前の演習で
$VMNAME
の変数はprodserver
に設定されています)。az vm identity show \ --name $VMNAME \ --resource-group "<rgn>[sandbox resource group name]</rgn>"
次のコードは、戻り値の例です。 ご自分の ID とは異なります。
{ "principalId": "aba6da53-9180-47fc-8fc4-4b35f154e845", "tenantId": "a95baa51-dcb1-4b9a-8312-8774a8afddbe", "type": "SystemAssigned", "userAssignedIdentities": null }
この値を使用して、次のコマンドでプリンシパル ID のみを返します。
キー コンテナー内のシークレットを取得して一覧表示するには、このプリンシパル ID を使用して VM を承認します。
az keyvault set-policy \ --name $KVNAME \ --secret-permissions get list \ --object-id $(az vm identity show \ --name $VMNAME \ --resource-group "<rgn>[sandbox resource group name]</rgn>" \ --output tsv \ --query principalId)
戻り値は JSON 形式になります。 これには、ID、場所、名前、および関連付けられているすべてのプロパティが含まれます。
再度アプリケーションをテストする
VM にサインインします。
ssh $publicIP
identity/secretapp
フォルダーに移動します。cd ~/identity/secretapp
アプリケーションを実行します。
dotnet run
今度は、アプリケーションで Key Vault からシークレットが取得され、その値が表示されます。
Database connection string:: Server=tcp:prodserverSQL.database.windows.net,1433;Database=myDataBase;User ID=mylogin@myserver;Password=examplePassword;Trusted_Connection=False;Encrypt=True;