チュートリアル: .NET デーモン アプリから保護された Web API を呼び出す

このチュートリアルは、.NET デーモン アプリから保護された Web API を呼び出す方法を示すシリーズの最後の部分です。 このシリーズのパート 1 では、.NET デーモン アプリを認可するように外部テナントを準備しました。 このチュートリアルでは、クライアント デーモン アプリをビルドし、保護された Web API を呼び出します。 クライアント デーモン アプリで独自の ID を使用してアクセス トークンを取得できるようにしてから、Web API を呼び出します。

このチュートリアルでは、

  • デーモン アプリを構成して、そのアプリの登録の詳細を使用します。
  • 独自にトークンを取得し、保護された Web API を呼び出すデーモン アプリをビルドします。

前提条件

.NET デーモン アプリを作成する

  1. ターミナルを開き、プロジェクトを公開するフォルダーに移動します。

  2. .NET コンソール アプリを初期化し、そのルート フォルダーに移動します。

    dotnet new console -n ToDoListClient
    cd ToDoListClient
    

パッケージをインストールする

Microsoft.Identity.Web パッケージと Microsoft.Identity.Web.DownstreamApi パッケージをインストールします。

dotnet add package Microsoft.Identity.Web
dotnet add package Microsoft.Identity.Web.DownstreamApi

Microsoft.Identity.Web を使用すると、ASP.NET Core、認証ミドルウェア、および .NET 用 Microsoft Authentication Library (MSAL) の間を結びつけることができるため、アプリに認証および承認機能を簡単に追加できます。 Microsoft.Identity.Web.DownstreamApi では、ダウンストリーム API を呼び出すために使用されるインターフェイスが提供されます。

登録構成を追加する appsettings.json ファイルを作成する

  1. アプリのルート フォルダーに appsettings.json ファイルを作成します。

  2. アプリの登録の詳細を appsettings.json ファイルに追加します。

    {
        "AzureAd": {
            "Authority": "https://<Enter_the_Tenant_Subdomain_Here>.ciamlogin.com/",
            "ClientId": "<Enter_the_Application_Id_here>",
            "ClientCredentials": [
                {
                    "SourceType": "ClientSecret",
                    "ClientSecret": "<Enter_the_Client_Secret_Here>"
                }
            ]
        },
        "DownstreamApi": {
            "BaseUrl": "<Web_API_base_url>",
            "RelativePath": "api/todolist",
            "RequestAppToken": true,
            "Scopes": [
                "api://<Enter_the_Web_Api_Application_Id_Here>/.default"
            ]
        }
    }
    

    次の値は固有の値に置き換えてください。

    説明
    Enter_the_Application_Id_Here 登録したクライアント デーモン アプリのアプリケーション (クライアント) ID。
    Enter_the_Tenant_Subdomain_Here ディレクトリ (テナント) サブドメイン。
    Enter_the_Client_Secret_Here 作成したデーモン アプリのシークレット値。
    Enter_the_Web_Api_Application_Id_Here 登録した Web API アプリのアプリケーション (クライアント) ID。
    Web_API_base_url Web API のベース URL。 例: https://localhost:44351/ (44351 は API が実行されているポートのポート番号)。 この値を取得するためには、この段階で既に API が実行され、要求を待っている必要があります。

モデルの追加

プロジェクト フォルダーのルートに移動し、models フォルダーを作成します。 models フォルダーに ToDo.cs ファイルを作成し、次のコードを追加します。

using System;

namespace ToDoListClient.Models;

public class ToDo
{
    public int Id { get; set; }
    public Guid Owner { get; set; }
    public string Description { get; set; } = string.Empty;
}

アクセス トークンを取得する

これで、デーモン アプリケーションに必要な項目が構成されました。 この手順では、デーモン アプリがアクセス トークンを取得できるようにするコードを記述します。

  1. コード エディターで program.cs ファイルを開き、その内容を削除します。

  2. ファイルにパッケージを追加します。

    using Microsoft.Extensions.DependencyInjection;
    using Microsoft.Identity.Abstractions;
    using Microsoft.Identity.Web;
    using ToDoListClient.Models;
    
  3. トークン取得インスタンスを作成します。 Microsoft.Identity.Web パッケージの TokenAcquirerFactory クラスの GetDefaultInstance メソッドを使用して、トークン取得インスタンスをビルドします。 既定では、アプリと同じフォルダーに存在する場合、インスタンスは appsettings.json ファイルを読み取ります。 GetDefaultInstance を使用すると、サービス コレクションにサービスを追加することもできます。

    次のコード行を program.cs ファイルに追加します。

    var tokenAcquirerFactory = TokenAcquirerFactory.GetDefaultInstance();
    
  4. 構成から読み取るアプリケーション オプションを構成し、DownstreamApi サービスを追加します。 DownstreamApi サービスでは、ダウンストリーム API を呼び出すために使用されるインターフェイスが提供されます。 config オブジェクトでこのサービス DownstreamAPI を呼び出します。 デーモン アプリは、appsettings.jsonDownstreamApi セクションからダウンストリーム API 構成を読み取ります。 既定では、メモリ内トークン キャッシュが取得されます。

    次のコード スニペットを program.cs ファイルに追加します。

    const string ServiceName = "DownstreamApi";
    
    tokenAcquirerFactory.Services.AddDownstreamApi(ServiceName,
        tokenAcquirerFactory.Configuration.GetSection("DownstreamApi"));
    
    
  5. トークンの取得プログラムをビルドします。 これにより、サービスに追加したすべてのサービスが構成され、サービス プロバイダーが返されます。 このサービス プロバイダーを使用して、追加した API リソースにアクセスします。 このケースでは、アクセスするダウンストリーム サービスとして API リソースを 1 つだけ追加しました。

    次のコード スニペットを program.cs ファイルに追加します。

    var serviceProvider = tokenAcquirerFactory.Build();
    

Web API を呼び出す

IDownstreamApi インターフェイスを使用して保護された Web API を呼び出すコードを追加します。 このチュートリアルでは、todo を Post するための呼び出しと、すべての todo を Get する別の呼び出しのみを実装します。 サンプル コードで Delete や Put などの他の実装を参照してください。

次のコード行を program.cs ファイルに追加します。

var toDoApiClient = serviceProvider.GetRequiredService<IDownstreamApi>();

Console.WriteLine("Posting a to-do...");

var firstNewToDo = await toDoApiClient.PostForAppAsync<ToDo, ToDo>(
    ServiceName,
    new ToDo()
    {
        Owner = Guid.NewGuid(),
        Description = "Bake bread"
    });

await DisplayToDosFromServer();
    
async Task DisplayToDosFromServer()
{
    Console.WriteLine("Retrieving to-do's from server...");
    var toDos = await toDoApiClient!.GetForAppAsync<IEnumerable<ToDo>>(
        ServiceName,
        options => options.RelativePath = "/api/todolist"
    );
    
    if (!toDos!.Any())
    {
        Console.WriteLine("There are no to-do's in server");
        return;
    }
    
    Console.WriteLine("To-do data:");
    
    foreach (var toDo in toDos!) {
        DisplayToDo(toDo);
    }
}

void DisplayToDo(ToDo toDo) {
    Console.WriteLine($"ID: {toDo.Id}");
    Console.WriteLine($"User ID: {toDo.Owner}");
    Console.WriteLine($"Message: {toDo.Description}");
}

クライアント デーモン アプリを実行する

デーモン アプリのルート フォルダーに移動し、次のコマンドを実行します。

dotnet run

問題がなければ、ターミナルに次の出力が表示されます。

Posting a to-do...
Retrieving to-do's from server...
To-do data:
ID: 1
User ID: 00001111-aaaa-2222-bbbb-3333cccc4444

Message: Bake bread

トラブルシューティング

エラーが発生した場合は、

  • appsettings.json ファイルに追加した登録の詳細を確認します。
  • 正しいポートおよび https 経由で Web API を呼び出していることを確認します。
  • アプリのアクセス許可が正しく構成されていることを確認します。

完全なサンプル コードは、GitHub で入手できます

リソースをクリーンアップする

このチュートリアルで登録および作成したアプリを使用しない場合は、コストが発生しないように削除してください。

関連項目