サービス プリンシパルを使用してローカル開発中に Azure サービスに対して .NET アプリを認証する

開発者は、ローカル ワークステーション上でクラウド アプリをデバッグしてテストする必要があります。 ローカル開発中にアプリを開発者のワークステーション上で実行する場合でも、そのアプリで使用されるすべての Azure サービスに対して認証する必要があります。 この記事では、ローカル開発時に使用する専用のアプリケーション サービス プリンシパル オブジェクトを設定する方法について説明します。

ローカルにインストールされた開発ツールを使用して、ローカルの .NET アプリが開発者の資格情報を使用して Azure に接続する方法を示すダイアグラム。

ローカル開発用の専用アプリケーション サービス プリンシパルを使用すると、アプリ開発時に最小限の特権の原則に従うことができます。 アクセス許可のスコープは開発中にそのアプリに必要なものに限定されるため、アプリ コードが、別のアプリでの使用を目的とした Azure リソースに誤ってアクセスすることが防止されます。 これにより、アプリが開発環境内で必要以上の特権を持っていたことが原因で、そのアプリを運用環境に移行した際にバグが発生することも防止されます。

アプリが Azure に登録されると、アプリケーション サービス プリンシパルがアプリ用に設定されます。 ローカル開発用にアプリを登録する場合は、次のことをお勧めします。

  • そのアプリで作業する開発者ごとに、個別のアプリ登録を作成します。 これにより、開発者ごとにローカル開発時に使用する個別のアプリケーション サービス プリンシパルが作成され、開発者が 1 つのアプリケーション サービス プリンシパルの資格情報を共有する必要がなくなります。
  • アプリごとに、個別のアプリ登録を作成します。 これにより、アプリのアクセス許可のスコープがアプリに必要なものだけに設定されます。

ローカル開発時に、環境変数はアプリケーション サービス プリンシパルの ID で設定されます。 Azure ID ライブラリでは、これらの環境変数を読み取り、この情報を使用して、必要な Azure リソースに対してアプリを認証します。

1 - Azure にアプリケーションを登録する

アプリケーション サービス プリンシパル オブジェクトは、Azure でアプリの登録を使用して作成されます。 これを行うには、Azure portal または Azure CLI のいずれかを使用します。

Azure portal にサインインして、次の手順を実行します。

手順 Screenshot
Azure portal で、次の操作を行います。
  1. Azure portal の上部にある検索バーに「アプリの登録」と入力します。
  2. 検索バーの下に表示されるメニューの [サービス] の下にある [アプリの登録] と書かれた項目を選択します。
Azure portal の上部の検索バーを使用して、[アプリの登録] ページを検索してそこに移動する方法を示すスクリーンショット。
[アプリの登録] ページで、[+ 新規登録] を選択します。 [アプリの登録] ページの [新規登録] ボタンの場所を示すスクリーンショット。
[アプリケーションの登録] ページで、次のようにフォームに入力します。
  1. 名前 → Azure でのアプリ登録の名前を入力します。 この名前には、アプリ名、アプリ登録の対象ユーザー、このアプリ登録がローカル開発での使用目的であることを示す識別子 ('dev' など) を含めることをお勧めします。
  2. [サポートされているアカウントの種類] → [この組織のディレクトリ内のアカウントのみ]。
[登録] を選択してアプリを登録し、アプリケーション サービス プリンシパルを作成します。
アプリに名前を付け、サポートされているアカウントの種類をこの組織ディレクトリ内のアカウントとしてのみ指定することで、[アプリケーションの登録] ページに入力する方法を示すスクリーンショット。
お使いのアプリの [アプリの登録] ページで、次の操作を行います。
  1. アプリケーション (クライアント) ID → ローカル開発時にアプリが Azure にアクセスするために使用するアプリ ID です。 この値は後の手順で必要になるため、テキスト エディター内の一時的な場所にコピーしてください。
  2. ディレクトリ (テナント) ID → この値は、Azure に対して認証するときにもアプリで必要になります。 この値も後の手順で必要になるため、テキスト エディター内の一時的な場所にコピーしてください。
  3. クライアント資格情報 → アプリが Azure に対して認証して Azure サービスを使用する前に、アプリのクライアント資格情報を設定する必要があります。 [証明書またはシークレットの追加] を選択して、アプリの資格情報を追加します。
アプリの登録が完了した後の [アプリの登録] ページのスクリーンショット。このスクリーンショットは、今後の手順で必要になるアプリケーション ID とテナント ID の場所を示しています。また、アプリのアプリケーション シークレットを追加するために使用するリンクの場所も示しています。
[証明書とシークレット] ページ上で、[+ 新しいクライアント シークレット] を選択します。 証明書とシークレット ページで新しいクライアント シークレットを作成するために使用するリンクの場所を示すスクリーンショット。
[クライアント シークレットの追加] ダイアログがページの右側から表示されます。 このダイアログで、次の操作を行います。
  1. 説明現在の値を入力します。
  2. 有効期限 → "24 か月"の値を選択します。
[追加] を選択してシークレットを追加します。
アプリ登録プロセスによって作成されるアプリケーション サービス プリンシパル用に新しいクライアント シークレットが追加されるページを示すスクリーンショット。
[証明書とシークレット] ページに、クライアント シークレットの値が表示されます。

この値は後の手順で必要になるため、テキスト エディター内の一時的な場所にコピーしてください。

重要: この値が表示されるのはこのタイミングだけです。 このページを終了または更新すると、この値を再度表示できなくなります。 このクライアント シークレットを無効にせずにさらにクライアント シークレットを追加することもできますが、この値はもう表示されなくなります。
生成されたクライアント シークレットを含むページを示すスクリーンショット。

2 - ローカル開発用に Microsoft Entra グループを作成する

通常、1 つのアプリに対して複数の開発者が作業するため、個々のサービス プリンシパル オブジェクトにロールを割り当てるのではなく、Microsoft Entra グループを作成して、ローカル開発でそのアプリに必要なロール (アクセス許可) をカプセル化することをお勧めします。 このアプローチには次の利点があります。

  • ロールはグループ レベルで割り当てられるため、すべての開発者に同じロールが割り当てられることが保証されます。
  • アプリに新しいロールが必要な場合は、そのアプリのグループに追加するだけで済みます。
  • 新しい開発者がチームに参加する場合は、アプリで作業するための適切なアクセス許可が開発者に与えられるように、その開発者用に新しいアプリケーション サービス プリンシパルを作成してグループに追加します。
手順 Screenshot
ページの上部にある検索ボックス内に「Microsoft Entra ID」と入力して、Azure portal 内の [Microsoft Entra ID] ページに移動します。 [サービス] セクションの下にある [Microsoft Entra ID] を選択します。 Azure portal の上部にある検索バーを使用して Microsoft Entra ID ページを検索し、移動する方法を示すスクリーンショット。
[Microsoft Entra ID] ページで、左側のメニューから [グループ] を選択します。 Microsoft Entra の [既定のディレクトリ] ページ左側のメニュー内にある [グループ] メニュー項目の場所を示すスクリーンショット。
[すべてグループ] ページで、[新しいグループ] を選択します。 [すべてのグループ] ページの [新しいグループ] ボタンの場所を示すスクリーンショット。
[新しいグループ] ページで、次の操作を行います。
  1. グループの種類セキュリティ
  2. グループ名 →通常はアプリケーション名から作成される、セキュリティ グループの名前です。 また、グループの目的も示すために、グループの名前に local-dev のような文字列を含めるとわかりやすくなります。
  3. グループの説明 → グループの目的の説明。
  4. [メンバー] の下の [メンバーが選択されていません] リンクを選択して、グループにメンバーを追加します。
フォームに入力して、アプリケーション用の新しい Microsoft Entra グループを作成する方法を示すスクリーンショット。このスクリーンショットには、このグループにメンバーを追加するために選択するリンクの場所も示されています。
[メンバーの追加] ダイアログ ボックスで、次の操作を行います。
  1. 検索ボックスを使用して、一覧で、プリンシパル名の一覧をフィルター処理します。
  2. このアプリのローカル開発用のアプリケーション サービス プリンシパルを選択します。 オブジェクトが選択されると、それらは灰色表示になり、ダイアログの下部にある [選択した項目] リストに移動します。
  3. 終わったら、[選択] ボタンを選択します。
グループに含めるアプリケーション サービス プリンシパルを選択する方法を示す [メンバーの追加] ダイアログ ボックスのスクリーンショット。
[新規グループ] ページに戻り、[作成] を選択して、グループを作成します。

グループが作成され、 [すべてのグループ] ページに戻ります。 そのグループが表示されるまでに最大 30 秒かかる場合があります。 Azure portal 内でのキャッシュにより、ページを更新する必要がある場合があります。
[作成] ボタンを選択してプロセスを完了する方法を示す [新しいグループ] ページのスクリーンショット。

3 - アプリケーションにロールを割り当てる

次に、アプリが何のリソースに対して何のロール (アクセス許可) が必要かを決定し、それらのロールをアプリに割り当てます。 この例では、手順 2 で作成した Microsoft Entra グループにロールが割り当てられます。 グループには、リソース、リソース グループ、またはサブスクリプションのスコープでロールを割り当てることができます。 ほとんどのアプリがすべての Azure リソースを 1 つのリソース グループ内にグループ化するため、この例ではリソース グループ スコープでロールを割り当てる方法を示します。

手順 Screenshot
Azure portal の上部にある検索ボックスを使用してリソース グループ名を検索し、そのアプリのリソース グループを見つけます。 ダイアログ ボックスの [リソース グループ] 見出しの下にあるリソース グループ名を選択して、リソース グループに移動します。 Azure portal の上部にある検索ボックスを使って、ロール (アクセス許可) の割り当て対象のリソース グループを検索してそこに移動する方法を示すスクリーンショット。
リソース グループのページで、左側のメニューから [アクセス制御 (IAM)] を選択します。 アクセス制御 (IAM) メニュー項目の場所を示すリソース グループ ページのスクリーンショット。
[アクセス制御 (IAM)] ページで、次の操作を行います。
  1. [ロールの割り当て] タブを選択します。
  2. 上部のメニューから [+ 追加] を選択し、次に結果のドロップダウン メニューから [ロールの割り当ての追加] を選択します。
[ロールの割り当て] タブへの移動方法と、ロールの割り当てをリソース グループに追加するボタンの場所を示すスクリーンショット。
[ロールの割り当ての追加] ページには、リソース グループで割り当てることができるすべてのロールが一覧表示されます。
  1. 検索ボックスを使用して、より管理しやすいサイズにリストをフィルター処理します。 この例では、Storage BLOB ロールをフィルター処理する方法を示します。
  2. 割り当てるロールを選択します。
[次へ] を選択して、次の画面に進みます。
リソース グループに追加するロールの割り当てを見つけるためにフィルター処理して選択する方法を示すスクリーンショット。
次の [ロールの割り当ての追加] ページでは、ロールを割り当てるユーザーを指定できます。
  1. [アクセスの割り当て先] で、[ユーザー、グループ、またはサービス プリンシパル] を選択します。
  2. [メンバー] の下にある [+ メンバーの選択] を選択します。
Azure portal の右側でダイアログ ボックスが開きます。
Microsoft Entra グループにロールを割り当てる際に選択するラジオ ボタンと、ロールを割り当てるグループを選択する際に使用されるリンクを示すスクリーンショット。
[メンバーの選択] ダイアログで、次の操作を行います。
  1. [選択] テキスト ボックスを使用して、サブスクリプション内のユーザーとグループの一覧をフィルター処理できます。 必要に応じて、アプリ用に作成したローカル開発 Microsoft Entra グループの最初の数文字を入力します。
  2. アプリケーションに関連付けられているローカル開発 Microsoft Entra グループを選択します。
ダイアログの下部にある [選択] を選択して続行します。
[メンバーの選択] ダイアログ ボックス内で、アプリの Microsoft Entra グループをフィルター処理して選択する方法を示すスクリーンショット。
Microsoft Entra グループが、[ロールの割り当ての追加] 画面に選択済みとして表示されます。 [レビューと割り当て] を選択して最終ページに移動し、もう一度レビューと割り当てを行ってプロセスを完了します。 完了した [ロールの割り当ての追加] ページと、プロセスを完了するために使用する [レビューと割り当て] ボタンの場所を示すスクリーンショット。

4 - アプリケーションの環境変数を設定する

実行時に、DefaultAzureCredential では環境変数のコレクション内のサービス プリンシパル情報が検索されます。 .NET で作業する場合、ツールと環境に応じて、環境変数を構成する方法は複数あります。

どのアプローチを選択するかにかかわらず、サービス プリンシパルで作業する場合は、次の環境変数を構成します。

  • AZURE_CLIENT_ID → アプリ ID の値です。
  • AZURE_TENANT_ID → テナント ID の値です。
  • AZURE_CLIENT_SECRET →アプリ用に生成されたパスワード/資格情報。

Visual Studio でローカルに作業する場合、環境変数はプロジェクトの Properties フォルダーにある launchsettings.json ファイルで設定できます。 アプリが起動すると、これらの値が自動的に取り込まれます。 これらの構成は配置時にアプリと一緒に移動しないため、ターゲットのホスティング環境上で環境変数を設定する必要があることに注意してください。

"profiles": {
    "SampleProject": {
      "commandName": "Project",
      "dotnetRunMessages": true,
      "launchBrowser": true,
      "applicationUrl": "https://localhost:7177;http://localhost:5177",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development",
        "AZURE_CLIENT_ID": "00000000-0000-0000-0000-000000000000",
        "AZURE_TENANT_ID":"11111111-1111-1111-1111-111111111111",
        "AZURE_CLIENT_SECRET": "=abcdefghijklmnopqrstuvwxyz"
      }
    },
    "IIS Express": {
      "commandName": "IISExpress",
      "launchBrowser": true,
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development",
        "AZURE_CLIENT_ID": "00000000-0000-0000-0000-000000000000",
        "AZURE_TENANT_ID": "11111111-1111-1111-1111-111111111111",
        "AZURE_CLIENT_SECRET": "=abcdefghijklmnopqrstuvwxyz"
      }
    }
  }

5 - アプリケーションに DefaultAzureCredential を実装する

DefaultAzureCredential は、Microsoft Entra に対して認証を行うための、厳格な、順序付けされたシーケンスのメカニズムです。 それぞれの認証メカニズムは、TokenCredential クラスから派生したクラスであり、"資格情報" と呼ばれます。 実行時に、DefaultAzureCredential は最初の資格情報を使用して認証を試みます。 その資格情報がアクセス トークンの取得に失敗した場合は、シーケンス内の次の資格情報が試みられ、正常にアクセス トークンが取得されるまでそれを続けます。 これにより、アプリは環境固有のコードを記述せずに、さまざまな環境でさまざまな資格情報を使用できます。

DefaultAzureCredential によって資格情報が検索される順序と場所は、DefaultAzureCredential にあります。

DefaultAzureCredential を使用するには、Azure.Identity と、必要に応じて Microsoft.Extensions.Azure パッケージをアプリケーションに追加します。

任意のターミナル内で、アプリケーションのプロジェクト ディレクトリに移動し、次のコマンドを実行します。

dotnet add package Azure.Identity
dotnet add package Microsoft.Extensions.Azure

Azure サービスには、さまざまな Azure SDK クライアント ライブラリの特殊なクライアント クラスを使用してアクセスします。 これらのクラスと独自のカスタム サービスは、アプリ全体で依存関係の挿入を介してアクセスできるように登録する必要があります。 Program.cs の中で、次の手順を実行してクライアント クラスと DefaultAzureCredential を登録します。

  1. using ディレクティブを介して Azure.IdentityMicrosoft.Extensions.Azure 名前空間を含めます。
  2. Add プレフィックスが付いた、対応する拡張メソッドを使用して、Azure サービス クライアントを登録します。
  3. UseCredential メソッドに DefaultAzureCredential のインスタンスを渡します。

次に例を示します。

using Microsoft.Extensions.Azure;
using Azure.Identity;

builder.Services.AddAzureClients(clientBuilder =>
{
    clientBuilder.AddBlobServiceClient(
        new Uri("https://<account-name>.blob.core.windows.net"));
    clientBuilder.UseCredential(new DefaultAzureCredential());
});

UseCredential の代替手段は、DefaultAzureCredential を直接インスタンス化することです。

using Azure.Identity;

builder.Services.AddSingleton<BlobServiceClient>(_ =>
    new BlobServiceClient(
        new Uri("https://<account-name>.blob.core.windows.net"),
        new DefaultAzureCredential()));

上記のコードをローカルの開発ワークステーション上で実行すると、環境変数内でアプリケーション サービス プリンシパルが検索されるか、ローカルにインストールされた開発者ツール (Visual Studio など) で開発者の資格情報のセットが検索されます。 どちらのアプローチも、ローカル開発中に Azure リソースに対してアプリを認証するために使用できます。

Azure に配置すると、この同じコードで、アプリを他の Azure リソースに対して認証することもできます。 DefaultAzureCredential では、環境設定とマネージド ID 構成を取得し、他のサービスに対して自動的に認証することができます。