演習 - マネージド 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 からシークレット情報をフェッチするアプリを作成する

  1. 先ほど作成した 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 コマンドを再実行します。

  2. identity/secretapp フォルダーに移動します。

    cd ~/identity/secretapp
    
  3. nano エディターを使って、Program.cs ファイルを開きます。

    nano Program.cs
    

    このファイルには、サンプル アプリの C# ソース コードが含まれています。

  4. Main メソッドを調べます。

    static async Task Main(string[] args)
    {
        await GetSecretFromKeyVault().ConfigureAwait(false);
    }
    

    このメソッドは、GetSecretFromKeyVault メソッドを呼び出すだけのアプリケーションのエントリ ポイントです。

  5. 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 インスタンスを使用して、キー コンテナーのシークレットにアクセスできます。

  6. コードの次の部分を見てください。

    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" に置き換えます。これは、キー コンテナーで作成したシークレットの名前です。

    このコード ブロックは、SecretClientGetSecretAsync メソッドを呼び出して、特定のシークレットを取得し、その値を表示します。 キーにアクセスするためのアクセス許可がクライアントにない場合、このコードは例外をスローし、エラー メッセージを表示します。

    Note

    パスワード、証明書、またはクライアント シークレットは、コードに格納されません。

  7. 変更を保存するには、Ctrl + O キーを押してから Enter キーを押します。

  8. nano エディターを閉じるには、Ctrl + X キーを押します。

アプリケーションをテストする

  1. 次のコマンドを実行して、アプリケーションをビルドします。

    dotnet restore
    dotnet build
    

    プログラムを正しく編集した場合は、エラーが発生せずにアプリがビルドされるはずです。

  2. アプリケーションを実行します。

    dotnet run
    

    キー コンテナーにアクセスするための VM のサービス プリンシパルをまだ承認していません。 したがって、アプリケーションは、次のエラー メッセージを表示して応答します。

    Something went wrong: Operation returned an invalid status code 'Forbidden'

サービス プリンシパルが Key Vault からシークレットを取得できるようにするためにアクセス許可を付与する

  1. VM への接続を閉じます。

    exit
    
  2. 前の演習で、ご自分の 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 のみを返します。

  3. キー コンテナー内のシークレットを取得して一覧表示するには、このプリンシパル 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、場所、名前、および関連付けられているすべてのプロパティが含まれます。

再度アプリケーションをテストする

  1. VM にサインインします。

    ssh $publicIP
    
  2. identity/secretapp フォルダーに移動します。

    cd ~/identity/secretapp
    
  3. アプリケーションを実行します。

    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;