次の方法で共有


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

ローカル開発時に、アプリケーションはさまざまな Azure サービスにアクセスするために Azure に対して認証を行う必要があります。 ローカル認証の 2 つの一般的な方法は、開発者アカウント またはサービス プリンシパルを 使用することです。 この記事では、アプリケーション サービス プリンシパルを使用する方法について説明します。 以下のセクションでは、次のことを説明します。

  • Microsoft Entra にアプリケーションを登録してサービス プリンシパルを作成する方法
  • Microsoft Entra グループを使用してアクセス許可を効率的に管理する方法
  • スコープのアクセス許可にロールを割り当てる方法
  • アプリ コードからサービス プリンシパルを使用して認証する方法

専用のアプリケーション サービス プリンシパルを使用すると、Azure リソースにアクセスするときに最小限の特権の原則に従うことができます。 アクセス許可は、開発中のアプリの特定の要件に制限され、他のアプリまたはサービスを対象とした Azure リソースへの誤ったアクセスを防ぎます。 この方法は、開発環境でアプリが過剰に特権を持たないようにすることで、アプリが運用環境に移行されたときの問題を回避するのにも役立ちます。

ローカル C++ アプリがサービス プリンシパルを使用して Azure リソースに接続する方法を示す図。

アプリが Azure に登録されると、アプリケーション サービス プリンシパルが作成されます。 ローカル開発の場合:

  • アプリで作業する開発者ごとに個別のアプリ登録を作成して、各開発者が独自のアプリケーション サービス プリンシパルを持っていることを確認し、資格情報を共有する必要がなくなります。
  • アプリのアクセス許可を必要なもののみに制限するには、アプリごとに個別のアプリ登録を作成します。

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

Azure にアプリを登録する

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

  1. Azure portal で検索バーを使用して、アプリの登録 ページに移動します。

  2. [アプリの登録] ページで、[+ 新規登録] を選択します。

  3. アプリケーションの登録ページ」で、次の手順を実行します。

    • [] フィールドに、アプリ名とターゲット環境を含むわかりやすい値を入力します。
    • [サポートされているアカウントの種類] で、この組織のディレクトリ内のアカウントのみ (Microsoft Customer Led only - Single tenant (Microsoft カスタマー主導の場合のみ - シングル テナント)) を選択するか、要件に最も適したオプションを選択します。
  4. [登録] を選択してアプリを登録し、サービス プリンシパルを作成します。

    Azure portal でアプリ登録を作成する方法を示すスクリーンショット。

  5. アプリの [アプリ登録] ページで、アプリケーション (クライアント) IDDirectory (テナント) ID コピーし、後でアプリ コード構成で使用できるように一時的な場所に貼り付けます。

  6. [証明書またはシークレットの追加] を選択して、アプリの資格情報を設定します。

  7. [証明書 & シークレット] ページで、[+ 新しいクライアント シークレット] を選択します。

  8. 開いた [クライアント シークレットの追加] ポップアップ パネルで次の操作を実行します。

    • [説明] に、Current の値を入力します。
    • の [有効期限] の値は、既定値の 180 日間のままにします。
    • [追加] を選択してシークレットを追加します。
  9. 証明書 & シークレット ページで、クライアント シークレットの Value プロパティをコピーして、今後の手順で使用してください。

    クライアント シークレットの値は、アプリの登録が作成された後に 1 回だけ表示されます。 このクライアント シークレットを無効にすることなく、クライアント シークレットをさらに追加できますが、この値を再度表示する方法はありません。

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

個々のサービス プリンシパル オブジェクトにロールを割り当てるのではなく、アプリがローカル開発で必要とするロール (アクセス許可) をカプセル化する Microsoft Entra グループを作成します。 この方法には、次の利点があります。

  • すべての開発者には、グループ レベルで同じロールが割り当てられます。
  • アプリに新しいロールが必要な場合は、アプリのグループにのみ追加する必要があります。
  • 新しい開発者がチームに参加すると、開発者用に新しいアプリケーション サービス プリンシパルが作成され、グループに追加され、開発者がアプリで作業するための適切なアクセス許可を持っている必要があります。
  1. Azure portal で Microsoft Entra ID の概要ページに移動します。

  2. 左側のメニューから [すべてのグループ ] を選択します。

  3. [ グループ ] ページで、[ 新しいグループ] を選択します。

  4. [ 新しいグループ ] ページで、次のフォーム フィールドに入力します。

    • グループの種類: セキュリティを選択します。
    • グループ名: アプリ名または環境名への参照を含むグループの名前を入力します。
    • グループの説明: グループの目的を説明する説明を入力します。

    Azure portal でグループを作成する方法を示すスクリーンショット。

  5. [メンバー] の下の [メンバーが選択されていません] リンクを選択して、グループにメンバーを追加します。

  6. 開いたポップアップ パネルで、先ほど作成したサービス プリンシパルを検索し、フィルター処理された結果から選択します。 パネルの下部にある [選択 ] ボタンを選択して、選択内容を確認します。

  7. [新しいグループ] ページの下部にある [作成] を選択してグループを作成し、[すべてのグループ] ページに戻ります。 新しいグループが表示されない場合は、しばらく待ってからページを更新してください。

グループにロールを割り当てる

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

  1. Azure portal で、アプリを含むリソース グループの [概要 ] ページに移動します。

  2. 左側のナビゲーションから アクセス制御 (IAM) を選択します。

  3. [ アクセス制御 (IAM)] ページで、[ + 追加 ] を選択し、ドロップダウン メニューから [ ロールの割り当ての追加 ] を選択します。 [ ロールの割り当ての追加] ページには、ロールを構成して割り当てるためのタブがいくつか用意されています。

  4. [ ロール ] タブで、検索ボックスを使用して、割り当てるロールを見つけます。 ロールを選択し、[ 次へ] を選択します。

  5. [メンバー] タブで、次の 手順 を実行します。

    • [ 値へのアクセスの割り当て] で、[ ユーザー、グループ、またはサービス プリンシパル ] を選択します。
    • [メンバー] の値で 、[+ メンバーの選択] を選択して、[メンバーの選択] ポップアップ パネルを開きます。
    • 先ほど作成した Microsoft Entra グループを検索し、フィルター処理された結果から選択します。 [ 選択 ] を選択してグループを選択し、ポップアップ パネルを閉じます。
    • [メンバー] タブの下部にある [確認と割り当て] を選択します。

    Microsoft Entra グループにロールを割り当てる方法を示すスクリーンショット。

  6. [ 校閲と割り当て ] タブで、ページの下部にある [校閲と割り当て ] を選択します。

アプリ環境変数を設定する

実行時に、 DefaultAzureCredentialEnvironmentCredentialClientSecretCredentialなど、Azure ID ライブラリの特定の資格情報は、環境変数の規則によってサービス プリンシパル情報を検索します。 ツールと環境に応じて環境変数を構成する方法は複数あります。 .env ファイルを作成することも、システム環境変数を使用して、開発中にこれらの資格情報をローカルに格納することもできます。

選択した方法に関係なく、サービス プリンシパルに対して次の環境変数を設定します。

  • AZURE_CLIENT_ID: Azure に登録されているアプリを識別するために使用されます。
  • AZURE_TENANT_ID: Microsoft Entra テナントの ID。
  • AZURE_CLIENT_SECRET: アプリ用に生成されたシークレット資格情報。

C++ アプリケーションの場合、これらの環境変数は複数の方法で設定できます。 コード内の .env ファイルから読み込んだり、システム環境で設定したりできます。 次の例は、さまざまなシェルで環境変数を設定する方法を示しています。

export AZURE_CLIENT_ID=<your-client-id>
export AZURE_TENANT_ID=<your-tenant-id>
export AZURE_CLIENT_SECRET=<your-client-secret>

アプリから Azure サービスに対して認証する

Azure Id ライブラリには、さまざまなシナリオと Microsoft Entra 認証フローのサポートに適応した TokenCredential の実装など、さまざまな資格情報が用意されています。 ローカルおよび運用環境でサービス プリンシパルを操作する場合は、 ClientSecretCredential クラスを使用します。 このシナリオでは、 ClientSecretCredential は環境変数 AZURE_CLIENT_IDAZURE_TENANT_ID、および AZURE_CLIENT_SECRET を読み取り、Azure に接続するためのアプリケーション サービス プリンシパル情報を取得します。

  1. vcpkg を使用して azure-identity-cpp パッケージをアプリケーションに追加します。

    vcpkg add port azure-identity-cpp
    
  2. CMake ファイルに次の行を追加します。

    find_package(azure-identity-cpp CONFIG REQUIRED)
    target_link_libraries(<your project name> PRIVATE Azure::azure-identity)
    
  3. アプリで Azure SDK クライアント オブジェクトを作成する C++ コードの場合:

    1. azure/identity.hpp ヘッダーを含めます。
    2. ClientSecretCredentialのインスタンスを作成します。
    3. ClientSecretCredentialのインスタンスを Azure SDK クライアント コンストラクターに渡します。

    例を次のコード セグメントに示します。

    #include <azure/identity.hpp>
    #include <azure/storage/blobs.hpp>
    #include <iostream>
    #include <memory>
    
    // The following environment variables must be set before running the sample.
    // * AZURE_TENANT_ID: Tenant ID for the Azure account.
    // * AZURE_CLIENT_ID: The Client ID to authenticate the request.
    // * AZURE_CLIENT_SECRET: The client secret.
    std::string GetTenantId() { return std::getenv("AZURE_TENANT_ID"); }
    std::string GetClientId() { return std::getenv("AZURE_CLIENT_ID"); }
    std::string GetClientSecret() { return std::getenv("AZURE_CLIENT_SECRET"); }
    
    int main() {
        try {
            // Create a credential - this will automatically read the environment variables
            // AZURE_CLIENT_ID, AZURE_TENANT_ID, and AZURE_CLIENT_SECRET
            auto credential = std::make_shared<Azure::Identity::ClientSecretCredential>(GetTenantId(), GetClientId(), GetClientSecret());
    
            // Create a client for the specified storage account
            std::string accountUrl = "https://<replace_with_your_storage_account_name>.blob.core.windows.net/";
            Azure::Storage::Blobs::BlobServiceClient blobServiceClient(accountUrl, credential);
    
            // Get a reference to a container
            std::string containerName = "sample-container";
            auto containerClient = blobServiceClient.GetBlobContainerClient(containerName);
    
            // Get a reference to a blob
            std::string blobName = "sample-blob";
            auto blobClient = containerClient.GetBlobClient(blobName);
    
            // TODO: perform some action with the blob client
            // auto downloadResult = blobClient.DownloadTo("path/to/local/file");
    
            std::cout << "Successfully authenticated and created Azure clients." << std::endl;
    
        } catch (const std::exception& ex) {
            std::cout << "Exception: " << ex.what() << std::endl;
            return 1;
        }
    
        return 0;
    }