チュートリアル: .NET デーモン アプリから保護された Web API を呼び出す
このチュートリアルは、.NET デーモン アプリから保護された Web API を呼び出す方法を示すシリーズの最後の部分です。 このシリーズのパート 1 では、.NET デーモン アプリを認可するように外部テナントを準備しました。 このチュートリアルでは、クライアント デーモン アプリをビルドし、保護された Web API を呼び出します。 クライアント デーモン アプリで独自の ID を使用してアクセス トークンを取得できるようにしてから、Web API を呼び出します。
このチュートリアルでは、
- デーモン アプリを構成して、そのアプリの登録の詳細を使用します。
- 独自にトークンを取得し、保護された Web API を呼び出すデーモン アプリをビルドします。
前提条件
.NET デーモン アプリを作成する
ターミナルを開き、プロジェクトを公開するフォルダーに移動します。
.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 ファイルを作成する
アプリのルート フォルダーに appsettings.json ファイルを作成します。
アプリの登録の詳細を 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;
}
アクセス トークンを取得する
これで、デーモン アプリケーションに必要な項目が構成されました。 この手順では、デーモン アプリがアクセス トークンを取得できるようにするコードを記述します。
コード エディターで program.cs ファイルを開き、その内容を削除します。
ファイルにパッケージを追加します。
using Microsoft.Extensions.DependencyInjection; using Microsoft.Identity.Abstractions; using Microsoft.Identity.Web; using ToDoListClient.Models;
トークン取得インスタンスを作成します。
Microsoft.Identity.Web
パッケージのTokenAcquirerFactory
クラスのGetDefaultInstance
メソッドを使用して、トークン取得インスタンスをビルドします。 既定では、アプリと同じフォルダーに存在する場合、インスタンスは appsettings.json ファイルを読み取ります。GetDefaultInstance
を使用すると、サービス コレクションにサービスを追加することもできます。次のコード行を program.cs ファイルに追加します。
var tokenAcquirerFactory = TokenAcquirerFactory.GetDefaultInstance();
構成から読み取るアプリケーション オプションを構成し、
DownstreamApi
サービスを追加します。DownstreamApi
サービスでは、ダウンストリーム API を呼び出すために使用されるインターフェイスが提供されます。 config オブジェクトでこのサービス DownstreamAPI を呼び出します。 デーモン アプリは、appsettings.json の DownstreamApi セクションからダウンストリーム API 構成を読み取ります。 既定では、メモリ内トークン キャッシュが取得されます。次のコード スニペットを program.cs ファイルに追加します。
const string ServiceName = "DownstreamApi"; tokenAcquirerFactory.Services.AddDownstreamApi(ServiceName, tokenAcquirerFactory.Configuration.GetSection("DownstreamApi"));
トークンの取得プログラムをビルドします。 これにより、サービスに追加したすべてのサービスが構成され、サービス プロバイダーが返されます。 このサービス プロバイダーを使用して、追加した 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: 00aa00aa-bb11-cc22-dd33-44ee44ee44ee
Message: Bake bread
トラブルシューティング
エラーが発生した場合は、
- appsettings.json ファイルに追加した登録の詳細を確認します。
- 正しいポートおよび https 経由で Web API を呼び出していることを確認します。
- アプリのアクセス許可が正しく構成されていることを確認します。
完全なサンプル コードは、GitHub で入手できます。
リソースをクリーンアップする
このチュートリアルで登録および作成したアプリを使用しない場合は、コストが発生しないように削除してください。