ユーザーを認証し、対話型エージェントのトークンを取得する

対話型エージェントは、ユーザーに代わってアクションを実行します。 エージェントは、ユーザーに代わって安全に操作するために、ユーザーを認証し、必要なアクセス許可に対する同意を取得し、ダウンストリーム API のアクセス トークンを取得します。 この記事では、対話型エージェントのエンド ツー エンド認証とトークン取得フローについて説明します。

  1. 継承可能なアクセス許可または同意を通じてアクセス許可を付与します。
  2. ユーザーを認証し、アクセス トークンを取得します。
  3. トークンを検証し、ユーザー要求を抽出します。
  4. On-Behalf-Of (OBO) フローを使用してダウンストリーム API のトークンを取得します。

この記事では、OBO フローを使用してサインインしているユーザー に代わって 動作する対話型エージェントについて説明します。 エージェントに独自のユーザーのような ID (デジタル ワーカー シナリオ) が必要な場合は、 エージェントのユーザー アカウントエージェントのユーザー アカウントの OAuth フローを参照してください。

前提条件

始める前に、以下のことを確認してください:

  • エージェント ID ブループリント。 エージェント ID ブループリント アプリ ID (クライアント ID) を記録します。
  • エージェント ID
  • ユーザー認証を処理するためにMicrosoft Entraに登録されているクライアント アプリケーション。
  • OAuth 2.0 承認コード フローに関する知識。
  • この記事のトークン検証と OBO サンプルを使用する予定の場合は、ASP.NET Core Web API を実行する機能。

管理者の承認には、次のものが必要です。

エージェントがユーザーの代わりに動作できるようにするには、ユーザーまたは管理者が必要なアクセス許可に同意する必要があります。 アクセス許可を付与するには、次の 2 つの方法があります。

  • 継承可能なアクセス許可: エージェント ID が自動的に継承されるように、ブループリントのアクセス許可を事前認証します。
  • 同意を要求する: リダイレクト URI を登録し、OAuth 要求を通じて同意を付与するか、管理者の同意エンドポイントを使用するようにユーザーまたは管理者に求めます。

継承可能なアクセス許可を使用する

委任されたスコープとアプリケーション ロールの基本セットを事前に認証するように、エージェント ID ブループリントに継承可能なアクセス許可を構成します。 ブループリントから作成されたエージェント ID は、対話型の同意プロンプトなしでこれらのアクセス許可を自動的に継承します。 詳細については、「 エージェント ID ブループリントの継承可能なアクセス許可を構成する」を参照してください。

OAuth フローを通じて同意を要求するには、まず、エージェント ID ブループリントをリダイレクト URI で構成する必要があります。 ブループリントの場合、リダイレクト URI は Web アプリケーション の種類である必要があります。 アプリ登録のリダイレクト URI とは異なり、ブループリントのリダイレクト URI を使用して委任されたアクセス許可トークンを取得することはできません。 OAuth2 要求では response_type=none のみがサポートされています。つまり、要求レコードは同意のみであり、トークンは返されません。

リダイレクト URI を登録する

エージェント ID ブループリントのリダイレクト URI を更新するには、まず、委任されたアクセス許可 AgentIdentityBlueprint.ReadWrite.Allを持つアクセス トークンを取得する必要があります。 次に、エージェント ID ブループリントのアプリケーション オブジェクトに PATCH 要求を送信します。

PATCH https://graph.microsoft.com/beta/applications/<agent-blueprint-id>
OData-Version: 4.0
Content-Type: application/json
Authorization: Bearer <token>

{
  "web": {
    "redirectUris": [
      "https://myagentapp.com/authorize"
    ]
  }
}

エージェントがユーザーの代わりに動作する前に、ユーザーは必要なアクセス許可に同意する必要があります。 ユーザーの同意要求はトークンを返しません。 代わりに、ユーザーがエージェントに代わって動作するアクセス許可を付与したことを記録します。 トークンの取得は、 ユーザーの認証とトークンの要求で行われます。

Important

エージェント ID ブループリント ID ではなく、client_id パラメーターでエージェント ID クライアント ID を使用します。

ユーザーに同意を求めるメッセージを表示するには、承認 URL を作成し、その URL にユーザーをリダイレクトします。 エージェントは、チャット メッセージ内のリンクなど、さまざまな方法でこの URL を表示できます。

https://login.microsoftonline.com/contoso.onmicrosoft.com/oauth2/v2.0/authorize?
  client_id=<agent-identity-id>
  &response_type=none
  &redirect_uri=https%3A%2F%2Fmyagentapp.com%2Fauthorize
  &response_mode=query
  &scope=User.Read
  &state=xyz123

ユーザーがこの URL を開くと、Microsoft Entra IDはサインインして同意を求めるメッセージを表示します。 同意すると、ユーザーはリダイレクト URI に送り返されます。

ユーザーの同意承認 URL の主要なパラメーターは次のとおりです。

  • client_id: エージェント ID クライアント ID (エージェント ID ブループリント クライアント ID ではありません)。
  • response_type: この要求では同意のみが記録されるため、 none に設定されます。 トークンの取得では、「ユーザーのresponse_type=codeを使用します。
  • redirect_uri: エージェント ID ブループリントで構成されたリダイレクト URI と正確に一致する必要があります。
  • scope: 必要な委任されたアクセス許可 (たとえば、 User.Read) を指定します。
  • state: 要求とコールバックの間の状態を維持するための省略可能なパラメーター。

OAuth 承認の概念の詳細については、Microsoft ID プラットフォーム の Permissions と同意に関するページを参照してください。

エージェントは、テナント内のすべてのユーザーに対してエージェントに同意を付与できる、Microsoft Entra ID管理者に承認を要求することもできます。 テナントで構成されている同意設定によっては、管理者の同意が必要になる場合があります。

テナント全体の管理者の同意を付与するには、管理者に次の URL を指示します。 client_id パラメーターでエージェント ID を使用します。

https://login.microsoftonline.com/contoso.onmicrosoft.com/v2.0/adminconsent
?client_id=<agent-identity-id>
&scope=User.Read
&redirect_uri=<redirect-uri>
&state=xyz123

管理者が同意を付与すると、アクセス許可はテナント全体に適用されます。 ユーザーはもう一度同意する必要はありません。

ブループリントでリダイレクト URI を構成し、同意要求に state パラメーターを含めます。 同意が付与されると、確認を表示できるリダイレクト URI にユーザーが送信されます。 エンドポイントでは、 state パラメーターを使用して、そのアクセス許可が付与されたことを追跡できます。 シングルテナント エージェントの場合は、テナント ID が既にわかっているため、同意が付与されるまでトークン要求を再試行することもできます。

ユーザーを認証し、トークンを要求する

同意が付与されると、クライアント アプリ (フロントエンドやモバイル アプリなど) が OAuth 2.0 承認コード要求を開始して、対象ユーザーがエージェント ID ブループリントであるトークンを取得します。 この手順では、 client_id は、エージェント ID またはエージェント ID ブループリントではなく、クライアント アプリ独自の登録済みアプリケーション ID を参照します。

この要求の redirect_uri は、前の同意手順で構成されたブループリントのリダイレクト URI ではなく、 クライアント アプリ の登録に属しています。

  1. 次のパラメーターを使用して、ユーザーを Microsoft Entra ID 承認エンドポイントにリダイレクトします。

    GET https://login.microsoftonline.com/<your-tenant-id>/oauth2/v2.0/authorize?client_id=<client-app-id>
    &response_type=code
    &redirect_uri=<redirect_uri>
    &response_mode=query
    &scope=api://<agent-blueprint-id>/access_agent
    &state=abc123
    
  2. ユーザーがサインインすると、アプリはリダイレクト URI で承認コードを受け取ります。 アクセス トークンの承認コードをExchangeします。

    POST https://login.microsoftonline.com/<your-tenant-id>/oauth2/v2.0/token
    Content-Type: application/x-www-form-urlencoded
    
    client_id=<client-app-id>
    &grant_type=authorization_code
    &code=<authorization_code>
    &redirect_uri=<redirect_uri>
    &scope=api://<agent-blueprint-id>/access_agent
    &client_secret=<client-secret>
    

    機密クライアントを使用している場合にのみ、 client_secret パラメーターを含めます。

    JSON 応答には、エージェントの API へのアクセスに使用できるアクセス トークンが含まれています。

アクセス トークンを検証する

Web API は、エージェントが動作する前に受信アクセス トークンを検証する必要があります。承認されたライブラリを常に使用してトークンを検証します。 独自のトークン検証コードを記述しないでください。

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

    dotnet add package Microsoft.Identity.Web
    
  2. ASP.NET Core Web API プロジェクトで、Microsoft Entra ID認証を実装します。

    // Program.cs
    using Microsoft.AspNetCore.Authentication.JwtBearer;
    using Microsoft.Identity.Web;
    
    var builder = WebApplication.CreateBuilder(args);
    
    builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
        .AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd"));
    
    var app = builder.Build();
    
    app.UseAuthentication();
    app.UseAuthorization();
    
  3. appsettings.json ファイルで認証資格情報を構成します。

    Warnung

    セキュリティ リスクのために、エージェント ID ブループリントの運用環境では、クライアント シークレットをクライアント資格情報として使用しないでください。 代わりに、マネージド ID またはクライアント証明書を使用 するフェデレーション ID 資格情報 (FIC) などのより安全な認証方法を使用してください。 これらの方法により、アプリケーション構成内に機密性の高いシークレットを直接格納する必要がなくなり、セキュリティが強化されます。

    "AzureAd": {
        "Instance": "https://login.microsoftonline.com/",
        "TenantId": "<your-tenant-id>",
        "ClientId": "<agent-blueprint-id>",
        "Audience": "<agent-blueprint-id>",
        "ClientCredentials": [
            {
                "SourceType": "ClientSecret",
                "ClientSecret": "your-client-secret"
            }
        ]
    }
    

Microsoft.Identity.Web の詳細については、Microsoft.Identity.Web ドキュメントをご参照ください。

ユーザー要求を検証する

アクセス トークンの検証後、エージェントはユーザーを識別し、承認チェックを実行できます。 次の API ルートの例では、アクセス トークンからユーザー要求を抽出し、API 応答で返します。

app.MapGet("/hello-agent", (HttpContext httpContext) =>
{   
    var claims = httpContext.User.Claims.Select(c => new
    {
        Type = c.Type,
        Value = c.Value
    });

    return Results.Ok(claims);
})
.RequireAuthorization();

ダウンストリーム API のトークンを取得する

対話型エージェントは、ユーザーのトークンを検証した後、アクセス トークンを要求して、ユーザーに代わってダウンストリーム API を呼び出すことができます。 On-Behalf-Of (OBO) フローを使用すると、エージェントは以下のことが可能です。

  • クライアントからアクセス トークンを受け取ります。
  • Microsoft Graph などのダウンストリーム API の新しいアクセス トークンに交換します。
  • その新しいトークンを使用して、元のユーザーの代わりに保護されたリソースにアクセスします。
  • Microsoft Identity Web
  • MICROSOFT GRAPH SDK

Microsoft.Identity.Web ライブラリは、トークン交換を自動的に処理することで OBO の実装を簡略化するため、プロトコルに従ってフローを手動で実装する必要はありません。

  1. 必要な NuGet パッケージをインストールします。

    dotnet add package Microsoft.Identity.Web
    dotnet add package Microsoft.Identity.Web.AgentIdentities
    
  2. ASP.NET Core Web API プロジェクトで、Microsoft Entra ID認証の実装を更新します。

    // Program.cs
    using Microsoft.AspNetCore.Authorization;
    using Microsoft.Identity.Abstractions;
    using Microsoft.Identity.Web;
    using Microsoft.Identity.Web.Resource;
    using Microsoft.Identity.Web.TokenCacheProviders.InMemory;
    
    var builder = WebApplication.CreateBuilder(args);
    
    builder.Services.AddMicrosoftIdentityWebApiAuthentication(builder.Configuration)
        .EnableTokenAcquisitionToCallDownstreamApi();
    builder.Services.AddAgentIdentities();
    builder.Services.AddInMemoryTokenCaches();
    
    var app = builder.Build();
    
    app.UseAuthentication();
    app.UseAuthorization();
    
    app.Run();
    
  3. エージェント API で、受信ユーザー アクセス トークンをエージェント ID の新しいアクセス トークンと交換します。 Microsoft.Identity.Web は、受信アクセス トークンを検証し、代理トークン交換を処理します。

    app.MapGet("/agent-obo-user", async (HttpContext httpContext) =>
    {
        string agentIdentity = "<your-agent-identity>";
        IAuthorizationHeaderProvider authorizationHeaderProvider = httpContext.RequestServices.GetService<IAuthorizationHeaderProvider>()!;
        AuthorizationHeaderProviderOptions options = new AuthorizationHeaderProviderOptions().WithAgentIdentity(agentIdentity);
    
        string authorizationHeaderWithUserToken = await authorizationHeaderProvider.CreateAuthorizationHeaderForUserAsync(["https://graph.microsoft.com/.default"], options);
    
        var response = new { header = authorizationHeaderWithUserToken };
        return Results.Json(response);
    })
    .RequireAuthorization();
    

内部的には、OBO フローには 2 つのトークン交換が含まれます。最初に、エージェント ID ブループリントはクライアント資格情報を使用して交換トークンを取得し、次にエージェント ID はそのトークンをダウンストリーム API トークンのユーザーのアクセス トークンと共に交換します。 HTTP 要求形式やトークン検証の詳細など、プロトコルの完全なチュートリアルについては、 エージェントでの On-behalf-of フローを参照してください。

エージェント トークンと関連 API の詳細については、以下を参照してください。