Web API を呼び出す Web アプリ: コード構成

ユーザーをサインインさせる Web アプリのシナリオで示されているように、Web アプリではユーザーをサインインさせるために OAuth 2.0 の承認コード フローが使用されます。 このフローには、次の 2 つのステップがあります。

  1. 承認コードを要求します。 この部分では、ユーザーとのプライベートな対話を Microsoft ID プラットフォームに委任します。 その対話の間に、ユーザーはサインインして Web API の使用に同意します。 プライベートな対話が正常に終了すると、Web アプリはそのリダイレクト URI での承認コードを受け取ります。
  2. 承認コードを引き換えることによって、API のアクセス トークンを要求します。

ユーザーをサインインさせる Web アプリのシナリオでは、最初のステップだけが説明されていました。 ここでは、ユーザーをサインインさせるだけでなく、Web API の呼び出しも行うように、Web アプリを変更する方法について説明します。

Web アプリをサポートしている Microsoft ライブラリ

次の Microsoft ライブラリで Web アプリがサポートされています。

言語/フレームワーク プロジェクト
GitHub
Package 取得
started
ユーザーのサインイン Web API へのアクセス 一般提供 (GA) または
パブリック プレビュー1
.NET MSAL.NET Microsoft.Identity.Client ライブラリでは、ユーザー サインインの ID トークンを要求できません。 ライブラリでは、保護された Web API のアクセス トークンを要求できます。 GA
.NET Microsoft.IdentityModel Microsoft.IdentityModel Library cannot request ID tokens for user sign-in.2 Library cannot request access tokens for protected web APIs.2 GA
ASP.NET Core ASP.NET Core Microsoft.AspNetCore.Authentication クイックスタート ライブラリでは、ユーザー サインインの ID トークンを要求できます。 ライブラリでは、保護された Web API のアクセス トークンを要求できません。 GA
ASP.NET Core Microsoft.Identity.Web Microsoft.Identity.Web クイックスタート ライブラリでは、ユーザー サインインの ID トークンを要求できます。 ライブラリでは、保護された Web API のアクセス トークンを要求できます。 GA
Java MSAL4J msal4j クイックスタート ライブラリでは、ユーザー サインインの ID トークンを要求できます。 ライブラリでは、保護された Web API のアクセス トークンを要求できます。 GA
Spring spring-cloud-azure-starter-active-directory spring-cloud-azure-starter-active-directory チュートリアル ライブラリでは、ユーザー サインインの ID トークンを要求できます。 ライブラリでは、保護された Web API のアクセス トークンを要求できます。 GA
Node.js MSAL Node msal-node クイックスタート ライブラリでは、ユーザー サインインの ID トークンを要求できます。 ライブラリでは、保護された Web API のアクセス トークンを要求できます。 GA
Python MSAL Python msal ライブラリでは、ユーザー サインインの ID トークンを要求できます。 ライブラリでは、保護された Web API のアクセス トークンを要求できます。 GA
Python identity identity クイックスタート ライブラリでは、ユーザー サインインの ID トークンを要求できます。 ライブラリでは、保護された Web API のアクセス トークンを要求できます。 --

(1)オンライン サービスのユニバーサル ライセンス条項は、"パブリック プレビュー" のライブラリに適用されます。

(2)Microsoft.IdentityModel ライブラリはトークンの "検証" のみを行います。ID やアクセス トークンを要求することはできません。

関心があるプラットフォームのタブを選択してください。

クライアント シークレットまたはクライアント証明書

ご利用の Web アプリでダウンストリーム Web API を呼び出すことができるようになったため、クライアント シークレットまたはクライアント証明書を appsettings.json ファイルに指定してください。 次を指定するセクションを追加することもできます。

  • ダウンストリーム Web API の URL
  • API の呼び出しに必要なスコープ

次の例では、GraphBeta セクションでこれらの設定を指定しています。

{
  "AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "ClientId": "[Enter_the_Application_Id_Here]",
    "TenantId": "common",

   // To call an API
   "ClientCredentials": [
    {
      "SourceType": "ClientSecret",
      "ClientSecret":"[Enter_the_Client_Secret_Here]"
    }
  ]
 },
 "GraphBeta": {
    "BaseUrl": "https://graph.microsoft.com/beta",
    "Scopes": ["user.read"]
    }
}

Note

Azure Kubernetes のワークロード ID フェデレーションのような資格情報のないソリューションなど、クライアント資格情報のコレクションを提案できます。 以前のバージョンの Microsoft.Identity.Web では、"ClientCredentials" ではなく単一のプロパティ "ClientSecret" でクライアント シークレットが表現されていました。 これは下位互換性のために引き続きサポートされていますが、"ClientSecret" プロパティと "ClientCredentials" コレクションの両方を使用することはできません。

クライアント シークレットの代わりに、クライアント証明書を指定することができます。 次のコード スニペットは、Azure Key Vault に格納されている証明書の使用を示しています。

{
  "AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "ClientId": "[Enter_the_Application_Id_Here]",
    "TenantId": "common",

   // To call an API
   "ClientCredentials": [
      {
        "SourceType": "KeyVault",
        "KeyVaultUrl": "https://msidentitywebsamples.vault.azure.net",
        "KeyVaultCertificateName": "MicrosoftIdentitySamplesCert"
      }
   ]
  },
  "GraphBeta": {
    "BaseUrl": "https://graph.microsoft.com/beta",
    "Scopes": ["user.read"]
  }
}

警告

Scopes を配列に変更することを忘れた場合、IDownstreamApi を使用しようとするとスコープに null が表示され、IDownstreamApi はダウンストリーム API に対して匿名 (非認証) の呼び出しを試み、その結果、401/unauthenticated が発生します。

Microsoft.Identity.Web では、構成またはコードの両方で証明書を記述するいくつかの方法を提供しています。 詳細については、GitHub 上の「Microsoft.Identity.Web - 証明書の使用」を参照してください。

Startup.cs

Web アプリでは、ダウンストリーム API のトークンを取得する必要があります。 これを指定するには、.AddMicrosoftIdentityWebApp(Configuration) の後に .EnableTokenAcquisitionToCallDownstreamApi() 行を追加します。 この行により、コントローラーおよびページのアクションで使用できる IAuthorizationHeaderProvider サービスが公開されます。 ただし、次の 2 つのオプションでわかるように、これはもっと簡単に行うことができます。 "Startup.cs" で、.AddInMemoryTokenCaches() などのトークン キャッシュの実装を選択する必要もあります。

using Microsoft.Identity.Web;

public class Startup
{
  // ...
  public void ConfigureServices(IServiceCollection services)
  {
  // ...
  services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
          .AddMicrosoftIdentityWebApp(Configuration, "AzureAd")
            .EnableTokenAcquisitionToCallDownstreamApi(new string[]{"user.read" })
            .AddInMemoryTokenCaches();
   // ...
  }
  // ...
}

EnableTokenAcquisitionToCallDownstreamApi に渡されるスコープは省略可能であり、Web アプリでサインイン時にスコープとそれらのスコープに対するユーザーの同意を要求できます。 スコープを指定しない場合は、Microsoft.Identity.Web によって、増分同意エクスペリエンスが有効になります。

"Microsoft.Identity.Web" には、トークンを取得しなくても Web アプリから Web API を呼び出すための 2 つのメカニズムが用意されています。 選択するオプションは、Microsoft Graph または別の API のどちらを呼び出すかによって異なります。

オプション 1: Microsoft Graph の呼び出し

Microsoft Graph を呼び出す場合は、Microsoft.Identity.Web を使用すると、API アクションで GraphServiceClient (Microsoft Graph SDK によって公開されている) を直接使用することができます。 Microsoft Graph を公開するには、次の手順を実行します。

  1. Microsoft.Identity.Web.GraphServiceClient NuGet パッケージをプロジェクトに追加します。

  2. Startup.cs ファイルで .EnableTokenAcquisitionToCallDownstreamApi() の後に .AddMicrosoftGraph() を追加します。 .AddMicrosoftGraph() にはいくつかのオーバーライドがあります。 構成セクションをパラメーターとして受け取るオーバーライドを使用すると、コードは次のようになります。

    using Microsoft.Identity.Web;
    
    public class Startup
    {
      // ...
      public void ConfigureServices(IServiceCollection services)
      {
      // ...
      services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
              .AddMicrosoftIdentityWebApp(Configuration, "AzureAd")
                .EnableTokenAcquisitionToCallDownstreamApi(new string[]{"user.read" })
                   .AddMicrosoftGraph(Configuration.GetSection("GraphBeta"))
                .AddInMemoryTokenCaches();
       // ...
      }
      // ...
    }
    

オプション 2:Microsoft Graph 以外のダウンストリーム Web API を呼び出す

Microsoft Graph ではなく API を呼び出す場合は、Microsoft.Identity.Web を使用すると、API アクションで IDownstreamApi インターフェイスを使用できます。 このインターフェイスを使用するには、以下を行います。

  1. Microsoft.Identity.Web.DownstreamApi NuGet パッケージをプロジェクトに追加します。

  2. Startup.cs ファイルで .EnableTokenAcquisitionToCallDownstreamApi() の後に .AddDownstreamApi() を追加します。 .AddDownstreamApi() には、次のスニペットに示すように 2 つの引数があります。

    • 対応する構成を参照するためにコントローラー アクションで使用されるサービスの名前 (API)
    • ダウンストリーム Web API の呼び出しに使用されるパラメーターを表す構成セクション。
    using Microsoft.Identity.Web;
    
    public class Startup
    {
      // ...
      public void ConfigureServices(IServiceCollection services)
      {
      // ...
      services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
              .AddMicrosoftIdentityWebApp(Configuration, "AzureAd")
                .EnableTokenAcquisitionToCallDownstreamApi(new string[]{"user.read" })
                   .AddDownstreamApi("MyApi", Configuration.GetSection("GraphBeta"))
                .AddInMemoryTokenCaches();
       // ...
      }
      // ...
    }
    

まとめ

Web API と同様に、さまざまなトークン キャッシュの実装を選択できます。 詳細については、GitHub の Microsoft.Identity.Web - トークン キャッシュのシリアル化のページを参照してください。

次の図は、Microsoft.Identity.Web のさまざまな可能性と、Startup.cs ファイルへの影響を示しています。

Web API を呼び出し、トークン キャッシュの実装を指定するための Startup.cs のサービス構成オプションを示すブロック図

注意

これらのコード例を完全に理解するために、ASP.NET Core の基礎、特に依存関係の挿入オプションについてよく理解してください。

承認コードを引き換えるコード

Microsoft.Identity.Web では、正しい OpenID Connect 設定を設定し、コードの受信イベントをサブスクライブして、コードを引き換えることで、コードを簡単にすることができます。 認可コードを引き換えるために、特別なコードは必要ありません。 この仕組みの詳細については、Microsoft.Identity.Web のソース コードをご覧ください。

機密クライアント アプリケーションでは、クライアント シークレットではなく、クライアント証明書またはクライアント アサーションを使用してその ID を証明することもできます。 クライアント アサーションの使用は高度なシナリオであり、詳細についてはクライアント アサーションに関するページをご覧ください。

トークンのキャッシュ

重要

Web アプリまたは Web API でのトークン キャッシュの実装は、ファイル ベースであることが多いデスクトップ アプリケーションでの実装とは異なります。 セキュリティとパフォーマンスのため、Web アプリと Web API では、ユーザー アカウントごとに 1 つのトークン キャッシュが存在することが重要です。 アカウントごとにトークン キャッシュをシリアル化する必要があります。

ASP.NET Core のチュートリアルでは、依存関係の挿入を使用して、アプリケーションの Startup.cs ファイルでトークン キャッシュの実装を決定できます。 Microsoft.Identity.Web には、「トークン キャッシュのシリアル化」で説明されている構築済みのトークン キャッシュ シリアライザーが付属しています。 興味深い可能性として、ASP.NET Core の分散メモリ キャッシュを選択できます。

// Use a distributed token cache by adding:
    services.AddMicrosoftIdentityWebAppAuthentication(Configuration, "AzureAd")
            .EnableTokenAcquisitionToCallDownstreamApi(
                initialScopes: new string[] { "user.read" })
            .AddDistributedTokenCaches();

// Then, choose your implementation.
// For instance, the distributed in-memory cache (not cleared when you stop the app):
services.AddDistributedMemoryCache();

// Or a Redis cache:
services.AddStackExchangeRedisCache(options =>
{
 options.Configuration = "localhost";
 options.InstanceName = "SampleInstance";
});

// Or even a SQL Server token cache:
services.AddDistributedSqlServerCache(options =>
{
 options.ConnectionString = _config["DistCache_ConnectionString"];
 options.SchemaName = "dbo";
 options.TableName = "TestCache";
});

トークン キャッシュ プロバイダーの詳細については、Microsoft.Identity.Web のトークン キャッシュのシリアル化に関する記事、および Web アプリのチュートリアルの ASP.NET Core Web アプリのチュートリアル | トークン キャッシュのフェーズもご覧ください。

次のステップ

この時点で、ユーザーがサインインすると、トークンはトークン キャッシュに格納されます。 それが Web アプリの他の部分でどのように使用されるかを見てみましょう。

このシナリオの次の記事、グローバル サインアウト時にキャッシュからアカウントを削除に関するページに進んでください。