Azure Cosmos DB for NoSQL アカウント キーを Azure Key Vault に格納する

Azure Cosmos DB アカウントの接続コードをアプリケーションに追加することは、アカウントの URI とキーを指定するのと同じように簡単です。 このセキュリティ情報は、アプリケーション コードにハード コーディングされている場合があります。 ただし、アプリケーションが Azure App Service に配置されている場合は、暗号化接続情報を Azure Key Vault に保存できます。

このラボでは、Azure Cosmos DB アカウント接続文字列を暗号化し、Azure Key Vault に保存します。 次に、これらの資格情報を Azure Key Vault から取得する Azure App Service Web アプリを作成します。 アプリケーションでは、これらの資格情報を使用し、Azure Cosmos DB アカウントに接続します。 その後、アプリケーションによって、Azure Cosmos DB アカウント コンテナーにいくつかのドキュメントが作成され、そのステータスが Web ページに戻されます。

開発環境を準備する

このラボで作業する環境に DP-420 のラボ コード リポジトリをまだクローンしていない場合は、次の手順に従ってそれを行います。 それ以外の場合は、以前にクローンしたフォルダーを Visual Studio Code で開きます。

  1. Visual Studio Code を起動します。

    📝 Visual Studio Code インターフェイスについてまだよく理解していない場合は、Visual Studio Code の入門ガイドに関するページ (code.visualstudio.com/docs/getstarted) を参照してください

  2. コマンド パレットを開き、Git: Clone を実行して、任意のローカル フォルダーに https://github.com/microsoftlearning/dp-420-cosmos-db-dev GitHub リポジトリをクローンします。

    💡 Ctrl + Shift + P キーボード ショートカットを使用してコマンド パレットを開くことができます。

  3. リポジトリが複製されたら、Visual Studio Code閉じます。 このファイルは、後で 28-key-vault フォルダーを直接ポイントして開きます。

Azure Cosmos DB for NoSQL アカウントを作成する

Azure Cosmos DB は、複数の API をサポートするクラウドベースの NoSQL データベース サービスです。 Azure Cosmos DB アカウントを初めてプロビジョニングするときに、アカウントでサポートする API を選択します (たとえば、Mongo APINoSQL API)。 Azure Cosmos DB for NoSQL アカウントのプロビジョニングが完了したら、エンドポイントとキーを取得できます。 エンドポイントとキーを使用して、Azure Cosmos DB for NoSQL アカウントにプログラムで接続します。 Azure SDK for .NET またはその他の SDK の接続文字列でエンドポイントとキーを使用します。

  1. 新しい Web ブラウザー ウィンドウまたはタブで、Azure portal (portal.azure.com) に移動します。

  2. ご利用のサブスクリプションに関連付けられている Microsoft 資格情報を使用して、ポータルにサインインします。

  3. [+ リソースの作成] を選択し、Cosmos DB を検索して、新しい Azure Cosmos DB for NoSQL アカウント リソースを作成します。以下を設定して、残りの設定はすべて既定値のままにします。

    設定 Value
    サブスクリプション ’‘既存の Azure サブスクリプション’’
    リソース グループ ’‘既存のリソース グループを選択するか、新しいものを作成します’’
    アカウント名 ’‘グローバルに一意の名前を入力します’’
    場所 ’‘使用可能なリージョンを選びます’’
    容量モード プロビジョニング済みスループット
    Apply Free Tier Discount (Free レベル割引の適用) 適用しない

    📝 ご利用のラボ環境には、新しいリソース グループを作成できない制限が存在する場合があります。 その場合は、事前に作成されている既存のリソース グループを使用します。

  4. デプロイ タスクが完了するまで待ってから、このタスクを続行してください。

  5. 新しく作成された Azure Cosmos DB アカウント リソースに移動し、 [キー] ペインに移動します。

  6. このペインには、SDK からアカウントに接続するために必要な接続の詳細と資格情報が含まれています。 具体的には、[プライマリ接続文字列] フィールドをコピーします。 この接続文字列の値は、この演習で後ほど使用します。

Azure Key Vault を作成し、Azure Cosmos DB アカウントの資格情報をシークレットとして保存する

Web アプリを作成する前に、Azure Key Vault で暗号化されたシークレットにコピーして、Azure Cosmos DB アカウントの接続文字列をセキュリティで保護します。 ここでは、その操作を行います。

  1. 新しいブラウザー タブで Azure portal に移動し、[キーの保管庫] ページを開きます。

  2. コンテナーを追加するには、[+ 作成] ボタンを選択します。次の設定でコンテナーを入力し、”残りのすべての設定を既定値のままにし”、それからコンテナーを作成するように選択します。**

    設定 Value
    サブスクリプション ’‘既存の Azure サブスクリプション’’
    リソース グループ ’‘既存のリソース グループを選択するか、新しいものを作成します’’
    キー コンテナー名 ’‘グローバルに一意の名前を入力します’’
    リージョン ’‘使用可能なリージョンを選びます’’
    アクセス構成/アクセス許可モデル Vault アクセス ポリシー
    アクセス構成/アクセス ポリシー 現在のユーザー名のチェック ボックスをオンにする

    📝 運用環境では、Vault アクセス ポリシーの代わりに RBAC 制御を選択する可能性が最も高く、管理者は Key Vault のアクセスを制限するために適切な RBAC ロールを割り当てる可能性が最も高い点に注意してください。

  3. コンテナーが作成されたら、コンテナーに移動します。

  4. [オブジェクト] セクションで、[シークレット] を選択します。

  5. [+ 生成/インポート] を選択して資格情報接続文字列を暗号化し、次の設定を使用してシークレット値を入力します。残りの設定はすべて既定値のままにし、その後シークレットの作成を選択します。

    設定 Value
    Upload options 手動
    名前 シークレットにラベル付けする名前
    Value このフィールドは、最も重要な入力フィールドです。Azure Cosmos DB アカウントのキー セクションのプライマリ接続文字列の値をここにコピーします。この値は、シークレットに変換されます。
    Enabled はい
  6. シークレットの下に、新しいシークレットが表示されます。 ここでは、Web アプリのコードに追加するシークレット識別子を取得する必要があります。 作成したシークレットを選択します。

  7. Azure Key Vault では、複数のバージョンのシークレットを作成できますが、このラボでは、1 つのバージョンのみが必要です。 現在のバージョンを選択します。

  8. [シークレット識別子] フィールドの値を記録します。 この値をアプリケーションのコードで使用して、Key Vault からシークレットを取得します。 この値は URL であることに注意してください。 このシークレットを正常に動作させるために必要な手順はもう 1 つありますが、その手順は後でもう少し行います。

Azure App Service Web アプリを作成する

Azure Cosmos DB アカウントに接続し、いくつかのコンテナーとドキュメントを作成する Web アプリを作成します。 このアプリでは Azure Cosmos DB の資格情報をハードコーディングすることはありませんが、代わりにキー コンテナーからシークレット識別子をハード コーディングしてください。 Azure レイヤーの Web アプリに適切な権限が割り当てられていなければ、この識別子が役に立たないということを確認します。 コーディングを始めましょう。

  1. Visual Studio Code を開きます。 28-key-vault フォルダーを開きます。[ファイル]、[フォルダーを開く] の順に選択し、28-key-vault フォルダーに到達するまで参照します。

    📝 [エクスプローラー] ツリーには、28-key-vault フォルダーとそのファイルとサブフォルダーのみが表示されるべきであることに注意してください。 前にクローンした GitHub リポジトリ全体が表示される場合は、Visual Studio Code を閉じて再度開き、28-key-vault フォルダーに直接移動します。 そのディレクトリがプロジェクトのルート ディレクトリでない場合、Web アプリは正しく動作しないため、28 key-vault フォルダーとそのファイルとサブフォルダーのみが [Explorer] ツリーに表示されることを確認してください。

  2. 28-key-vault フォルダーのコンテキスト メニューを開き、[統合ターミナルで開く] を選択して新しいターミナル インスタンスを開きます。

    📝 このコマンドを実行すると、開始ディレクトリが 28-key-vault フォルダーに既に設定されているターミナルが開きます。

  3. MVC Web アプリ シェルを作成しましょう。 後で生成されたファイルをいくつか置き換えます。 次のコマンドを実行して Web アプリを作成します。

     dotnet new mvc
    

    このコマンドによって Web アプリのシェルが作成されたので、複数のファイルとディレクトリが追加されました。 必要なすべてのコードを含むファイルが既に 2 つ存在します。

  4. .\KeyvaultFiles ディレクトリ内のそれぞれのファイルについて、ファイル .\Controllers\HomeController.cs.\Views\Home\Index.cshtml を置き換えます。

  5. ファイルを置き換えたら、.\KeyvaultFiles ディレクトリに対して DELETE を実行します。

不足している複数のライブラリを .NET スクリプトにインポートする

.NET CLI には、パッケージの追加 (docs.microsoft.com/dotnet/core/tools/dotnet-add-package) コマンドが含まれています。事前構成済みのパッケージ フィードからパッケージをインポートします。 .NET インストールでは、既定のパッケージ フィードとして NuGet が使用されます。

  1. 次のコマンドを使用して、NuGet から Microsoft.Azure.Cosmos (nuget.org/packages/microsoft.azure.cosmos/3.22.1) パッケージを追加します。

     dotnet add package Microsoft.Azure.Cosmos --version 3.22.1
    
  2. 次のコマンドを使用して、NuGet から Newtonsoft.Json (nuget.org/packages/Newtonsoft.Json/13.0.1) パッケージを追加します。

     dotnet add package Newtonsoft.Json --version 13.0.1
    
  3. 次のコマンドを使用して、NuGet から Microsoft.Azure.KeyVault (nuget.org/packages/Microsoft.Azure.KeyVault) パッケージを追加します。

     dotnet add package Microsoft.Azure.KeyVault
    
  4. 次のコマンドを使用して、NuGet から Microsoft.Azure.Services.AppAuthentication (nuget.org/packages/Microsoft.Azure.Services.AppAuthentication) パッケージを追加します。

     dotnet add package Microsoft.Azure.Services.AppAuthentication --version 1.6.2
    

Web アプリにシークレット識別子を追加する

  1. Visual Studio で、.\Controllers\HomeControler.cs ファイルを開きます

  2. GetKeyVaultSecret ユーザー定義関数では、Azure Cosmos DB アカウント シークレットを取得します。 関数は 98 行目から始まるので、次のスクリプトのようになります。

        private static async Task<Tuple<bool,string>>  GetKeyVaultSecret()
        {
            AzureServiceTokenProvider azureServiceTokenProvider = new AzureServiceTokenProvider("RunAs=App;");

            try
            {
                var KVClient = new KeyVaultClient(
                    new KeyVaultClient.AuthenticationCallback(azureServiceTokenProvider.KeyVaultTokenCallback));

                var KeyVaultSecret = await KVClient.GetSecretAsync("<Key Vault Secret Identifier>")
                    .ConfigureAwait(false);

                return new Tuple<bool,string>(true, KeyVaultSecret.Value.ToString());

            }
            catch (Exception exp)
            {
                return new Tuple<bool,string>(false, exp.Message);
            }

        }
  1. この関数が行う重要な呼び出しを確認しましょう。

    • 100 行目では、現在の Web アプリのトークンを定義します。 このトークンは、コンテナーにアクセスしようとしているアプリを識別するために、Azure Key Vault に提供されます。
    • 104 から 105 行目では、Azure Key Vault に接続する Key Vault Client クライアントを準備します。 Web アプリ トークンをパラメーターとして送信することに注目してください。
    • 107 から 108 行目では、Key Vault クライアントにシークレット識別子の URL アドレスを提供します。これは、そのキー コンテナーに格納されているシークレットを返します。
  2. Web アプリをデプロイする前に、依然としてシークレット識別子 URL を送信する必要があります。 107 行目で、文字列 ****** を *[シークレット]* セクションに記録した**シークレット識別子** URL に置き換え、ファイルを保存します。

        var KeyVaultSecret = await KVClient.GetSecretAsync("<Key Vault Secret Identifier>")

(省略可能) Azure App Services 拡張機能をインストールする

Visual Studio でコマンド パレット (Ctrl + Shift + P) を起動しても、Azure App リソース コマンドを検索しても何も返されない場合は、拡張機能をインストールする必要があります。

  1. Visual Studio Code の左側メニューで、[拡張機能] オプションを選択します。

  2. 検索バーで、Azure App Service を検索して選択します。

  3. [インストール] ボタンを選択してインストールします。

  4. [拡張機能] タブを閉じて、コードに戻ります。

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

コードの残りの部分は簡単です。接続文字列を取得し、Azure Cosmos DB に接続して、いくつかのドキュメントを追加します。 アプリケーションでは、問題に関するフィードバックも提供する必要があります。 アプリケーションをデプロイした後で、それ以上の変更を行う必要はないようにする必要があります。 では、始めましょう。

📝 以下の手順のほとんどは、Visual Studio 画面の上部中央にあるコマンド パレット (Ctrl + Shift + P) で実行されます。

  1. Visual Studio Code で、コマンド パレットを開き、Azure App Service: 新しい Web アプリの作成 (詳細) を検索します

  2. [Azure へのサインイン…] を選択します。このオプションを選択すると、Web ブラウザー ウィンドウが開きます。サインイン プロセスに従い、完了したらブラウザーを閉じて Visual Studio Code に戻ります。

  3. (省略可能) サブスクリプションを要求する場合は、サブスクリプションを選択します。

  4. グローバルに一意の Web アプリ名を入力します。

  5. 必要な場合、既存のリソース グループを選択するか、新しいリソース グループを作成します。

  6. [.NET 6 (LTS)] を選択します。

  7. [Windows] を選択します。

  8. 使用可能な [場所] を選択します。

  9. [+ 新しい App Service プランの作成] を選択します。

  10. App Service プランの既定の名前を受け入れるか (Web アプリ名と同じ名前にしてください)、新しい名前を選択します。

  11. [Free (F1) 無料で Azure を試す] を選択します。

  12. Application Insights については、[今はスキップ] を選択します。

  13. デプロイが、右下隅のステータス バーで実行中になっているはずです。

  14. 確認を求められたら [デプロイ] を選択します。

  15. [参照] を選択すると、28-key-vault フォルダー内になるはずです。そのフォルダーを選択します。

  16. “28-key-vault” にデプロイに必要な構成が見つかりませんというメッセージが表示されたポップアップが表示されたら、[構成の追加] ボタンを選択します。 このオプションを選択すると、不足している .vscode フォルダーが作成されます。

    📝 非常に重要なのは、このポップアップがアプリの最初のデプロイに表示されない場合、Azure App Services へのアップロードでファイルが不足しています。 デプロイは成功しますが、Web サイトでは常に、このディレクトリまたはページを表示するアクセス許可が付与されていませんというメッセージが返されます。 最も可能性の高い原因は、Visual Studio Code が 28-key-vault フォルダーのみではなく、GitHub Cloned リポジトリで開かれたということです。

  17. 常にそのワークスペースにデプロイするように求めるプロンプトで、[はい] を選択します。

  18. メッセージが表示されたら、[Web サイトの参照] を選択します。 または、ブラウザーを開き、https://<yourwebappname>.azurewebsites.net に移動します。 どちらの場合も、問題があります。 Web ページにユーザー定義メッセージが表示されます。 拡張エラー メッセージとKey Vault にアクセスできませんでしたというメッセージが表示されます。 これを修正してみましょう。

アプリでマネージド ID の使用を許可する

修正する必要がある最初の問題は、アプリでマネージド ID を使用できるようにすることです。 マネージド ID を使用すると、Azure Key Vault などの Azure サービスをアプリで使用できます。

  1. ブラウザーを開き、Azure portal にログインします。

  2. [App Services] ページを開きます。 Web アプリ名が一覧表示されるので、それを選択します。

  3. [設定] セクションで、[ID] を選択します。

  4. [状態] で、[オン][保存] を選択します。 割り当てられたマネージド ID を有効にするプロンプトで、[はい] を選択します。

  5. もう一度 Web アプリを試しましょう。 ブラウザーで https://<yourwebappname>.azurewebsites.net に移動します。

  6. まだ 1 つの問題があります。 最初のメッセージはプログラムから送信されているユーザー定義メッセージですが、2 番目のメッセージはシステムによって生成されたメッセージです。 2 番目のメッセージは、Key Vault への接続へのアクセスが許可されているが、コンテナー内のシークレットを表示するためのアクセス権が付与されていないという意味です。 この問題を解決するための最後に 1 つ設定しましょう。

Web アプリケーションに Key Vault シークレットへのアクセス ポリシーを付与する

このラボの当初の目標は、Azure Cosmos DB アカウントがアプリケーションでハードコーディングされるのを防ぐことでした。 しかし、誰でも確認できるシークレット識別子 URL をハード コーディングしました。 では、資格情報をセキュリティで保護するにはどうすれば良いでしょうか。 幸い、シークレット識別子そのものだけでは役に立ちません。 シークレット識別子では Azure Key Vault のドアまでアクセスできず、コンテナーで誰が入れるか、誰がドアにとどまるのかを決定します。 これは、アプリケーションからそのコンテナー内のシークレットを確認できるよう、Key Vault アクセス ポリシーを作成する必要があるということを意味します。 その解決策を見てみしましょう。

  1. (省略可能) ポリシーを作成する前に、Azure Cosmos DB データベースの現在の内容を確認しましょう。 Azure portal で、Azure Cosmos DB アカウントに移動します。GlobalCustomers データベースはありますか。 ない場合は、Web アプリの正常な実行によって作成されます。 ある場合は、データベース内の項目の数を確認します。Web アプリが正常に実行されると、項目が追加されます。

  2. Azure portal で、前に作成したキー コンテナーに移動します。

  3. [設定] セクションで、[アクセス構成] を選択します。

  4. [Vault access policy] (コンテナー アクセス ポリシー) が選択されていることを確認して、[アクセス ポリシーに移動] を選びます。

  5. [+ 作成] を選択します。

  6. [アクセス許可] タブで、[キーのアクセス許可][シークレットのアクセス許可][取得] チェック ボックスをオンにして、[次へ] を選びます。

  7. [プリンシパル] タブの検索ボックスに、自分の App Service に指定した名前を入力し、一覧からそれを選んで、[次へ] を選びます。

  8. [アプリケーション (省略可能)] タブで、[次へ] を選びます。

  9. [確認および作成] タブで、 [作成] を選択します。

  10. もう一度 Web アプリを試しましょう。 ブラウザーで https://<yourwebappname>.azurewebsites.net に移動します。

  11. Success! Web ページには、customer コンテナーに新しい項目を挿入したことが示されています。 また、実際に表示されているシークレットを確認することもできます。

    📝 運用環境では決してシークレットが表示しないでください。これは説明のために行いました。

  12. Azure Cosmos DB アカウントにアクセスし、データが含まれた新しい GlobalCustomers データベースがあるか、あるいはデータベースが既に存在する場合は、データベース内に項目が追加で存在するかどうかを確認します。

これで、Azure Key Vault を適切に使用して、Azure Cosmos DB アカウントのキーを保護できました。