カスタム クレーム プロバイダーのトークン発行イベントを構成する (プレビュー)

この記事では、トークン発行開始イベントの種類を使ってカスタム クレーム プロバイダーを構成および設定する方法について説明します。 トークンが発行される直前にトリガーされるこのイベントを使うと、REST API を呼び出してトークンにクレームを追加できます。

この攻略ガイドでは、Azure Functions で実行されている REST API と OpenID Connect のサンプル アプリケーションで、トークン発行開始イベントを実際に使ってみます。 開始する前に、Function アプリで Microsoft Entra カスタム クレーム プロバイダーを構成する方法を示す次のビデオをご覧ください:

前提条件

手順 1: Azure 関数アプリを作成する

ヒント

この記事の手順は、開始するポータルによって若干異なる場合があります。

このステップでは、Azure portal で HTTP トリガー関数 API を作成します。 関数 API は、トークンに対する追加クレームのソースです。 Azure 関数を作成するには、次の手順のようにします。

  1. 管理者アカウントで Azure Portal にサインインします。

  2. Azure portal のメニューまたは [ホーム] ページから [リソースの作成] を選択します。

  3. [新規] ページで、 [計算]>、 [関数アプリ] の順に選択します。

  4. [基本] ページで、下の表に指定されている関数アプリの設定を使用します。

    設定 提案された値 説明
    サブスクリプション 該当するサブスクリプション 新しい関数アプリを作成するサブスクリプション。
    リソース グループ myResourceGroup 関数アプリを作成する、既存のリソース グループを選ぶか、新しいリソース グループの名前を選びます。
    関数アプリ名 グローバルに一意の名前 新しい関数アプリを識別する名前。 有効な文字は、a-z (大文字と小文字の区別をしない)、0-9、および -です。
    発行 コード コード ファイルまたは Docker コンテナーの発行オプション。 このチュートリアルでは、[コード] を選びます。
    ランタイム スタック .NET 好みのプログラミング言語。 このチュートリアルでは、[.NET] を選びます。
    Version 6 .NET ランタイムのバージョン。
    リージョン 優先リージョン 自分の近く、または関数がアクセスできる他のサービスの近くのリージョンを選択します。
    オペレーティング システム Windows オペレーティング システムは、ランタイム スタックの選択に基づいて、事前に自動的に選択されます。
    [プランの種類] "従量課金 (サーバーレス)" Function App にどのようにリソースが割り当てられるかを定義するホスティング プラン。
  5. [確認および作成] を選んでアプリの構成の選択を確認した後、[作成] を選びます。

  6. ポータルの右上隅の [通知] アイコンを選択し、"デプロイメントに成功しました" というメッセージが表示されるまで待ちます。 次に、[リソースに移動] を選んで、新しい関数アプリを確認します。

1.1 HTTP トリガー関数を作成する

Azure 関数アプリが作成されたら、HTTP トリガー関数を作成します。 HTTP トリガーでは、HTTP 要求で関数を呼び出すことができます。 この HTTP トリガーは、Microsoft Entra カスタム認証拡張機能によって参照されて呼び出されます。

  1. [関数アプリ] 内で、メニューから [関数] を選びます。
  2. 上部のメニューから、[+ 作成] を選びます。
  3. [関数の作成] ウィンドウで、[開発環境] プロパティは [Develop in portal] (ポータルで開発) のままにして、[HTTP トリガー] テンプレートを選びます。
  4. [テンプレートの詳細] で、[新しい関数] プロパティに「CustomAuthenticationExtensionsAPI」と入力します。
  5. [認証レベル][関数] を選びます。
  6. [作成]

次のスクリーンショットは、Azure HTTP トリガー関数の構成方法を示したものです。

Screenshot that shows how to choose the development environment, and template.

1.2 関数を編集する

  1. メニューから [Code + Test] (コードとテスト) を選びます

  2. コード全体を次のコード スニペットに置き換えます。

    #r "Newtonsoft.Json"
    using System.Net;
    using Microsoft.AspNetCore.Mvc;
    using Microsoft.Extensions.Primitives;
    using Newtonsoft.Json;
    public static async Task<IActionResult> Run(HttpRequest req, ILogger log)
    {
        log.LogInformation("C# HTTP trigger function processed a request.");
        string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
        dynamic data = JsonConvert.DeserializeObject(requestBody);
    
        // Read the correlation ID from the Azure AD  request    
        string correlationId = data?.data.authenticationContext.correlationId;
    
        // Claims to return to Azure AD
        ResponseContent r = new ResponseContent();
        r.data.actions[0].claims.CorrelationId = correlationId;
        r.data.actions[0].claims.ApiVersion = "1.0.0";
        r.data.actions[0].claims.DateOfBirth = "01/01/2000";
        r.data.actions[0].claims.CustomRoles.Add("Writer");
        r.data.actions[0].claims.CustomRoles.Add("Editor");
        return new OkObjectResult(r);
    }
    
    public class ResponseContent{
        [JsonProperty("data")]
        public Data data { get; set; }
        public ResponseContent()
        {
            data = new Data();
        }
    }
    
    public class Data{
        [JsonProperty("@odata.type")]
        public string odatatype { get; set; }
        public List<Action> actions { get; set; }
        public Data()
        {
            odatatype = "microsoft.graph.onTokenIssuanceStartResponseData";
            actions = new List<Action>();
            actions.Add(new Action());
        }
    }
    
    public class Action{
        [JsonProperty("@odata.type")]
        public string odatatype { get; set; }
        public Claims claims { get; set; }
        public Action()
        {
            odatatype = "microsoft.graph.tokenIssuanceStart.provideClaimsForToken";
            claims = new Claims();
        }
    }
    
    public class Claims{
        [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
        public string CorrelationId { get; set; }
        [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
        public string DateOfBirth { get; set; }
        public string ApiVersion { get; set; }
        public List<string> CustomRoles { get; set; }
        public Claims()
        {
            CustomRoles = new List<string>();
        }
    }
    

    コードは、受信した JSON オブジェクトの読み取りから始まります。 Microsoft Entra ID は、JSON オブジェクトを API に送信します。 この例では、関連付け ID の値を読み取ります。 次に、コードから、元の関連付け ID、Azure 関数のバージョン、生年月日、Microsoft Entra ID に返されるカスタム ロールなど、クレームのコレクションが返されます。

  3. 上部のメニューから [関数の URL の取得] を選んで、URL をコピーします。 次のステップでは、この関数の URL を {Function_Url} として参照します。

手順 2: カスタム認証拡張機能を登録する

このステップでは、Microsoft Entra ID が Azure 関数を呼び出すために使用するカスタム認証拡張機能を構成します。 カスタム認証拡張機能には、REST API エンドポイントに関する情報、REST API から解析するクレーム、REST API に対する認証方法が含まれています。 次の手順のようにして、カスタム認証拡張機能を登録します。

  1. アプリケーション管理者および認証管理者以上の権限で Microsoft Entra 管理センターにサインインします。

  2. ID>アプリケーション>エンタープライズ アプリケーション を参照します。

  3. [カスタム認証拡張機能] を選択して、[カスタム認証拡張機能の作成] を選択します。

  4. [基本]tokenIssuanceStart イベントを選んで、[次へ] を選びます。

  5. [エンドポイントの構成] で、次のプロパティを入力します。

    • [名前] - カスタム認証拡張機能の名前。 例: "トークン発行イベント"。
    • [ターゲット URL] - Azure 関数の URL の {Function_Url}
    • [説明] - カスタム認証拡張機能の説明。
  6. [次へ] を選択します。

  7. [API 認証][アプリの登録を新規作成する] オプションを選んで、"関数アプリ" を表すアプリ登録を作成します。

  8. アプリの名前を指定します (例: Azure Functions 認証イベント API)。

  9. [次へ] を選択します。

  10. [要求] に、カスタム認証拡張機能で REST API から解析されてトークンにマージされる属性を入力します。 次のクレームを追加します。

    • dateOfBirth
    • customRoles
    • apiVersion
    • correlationId
  11. [次へ][作成] の順に選択します。これにより、カスタム認証拡張機能とそれに関連付けられているアプリケーションの登録が登録されます。

カスタム認証拡張機能が作成されると、新しいカスタム認証拡張機能の [概要] タブを開きます。

[概要] ページで、[アクセス許可の付与] ボタンを選んで、登録済みアプリに管理者の同意を付与します。これにより、カスタム認証拡張機能は API に対する認証を行えるようになります。 カスタム認証拡張機能は、client_credentials を使い、Receive custom authentication extension HTTP requests アクセス許可を使って Azure Function App に対する認証を行います。

アクセス許可を付与する方法を示すスクリーンショットを次に示します。

Screenshot that shows how grant admin consent.

手順 3: エンリッチされたトークンを受信するように OpenID Connect アプリを構成する

トークンを取得してカスタム認証拡張機能をテストするには、https://jwt.ms アプリを使用できます。 これは Microsoft 所有の Web アプリケーションであり、トークンのデコードされた内容を表示します (トークンの内容がお使いのブラウザーの外に出ることはありません)。

次の手順のようにして、jwt.ms Web アプリケーションを登録します。

3.1 テスト Web アプリケーションを登録する

  1. アプリケーション管理者以上の権限で Microsoft Entra 管理センターにサインインします。
  2. [ID]>[アプリケーション]>[Application registrations] (アプリケーションの登録) を参照します。
  3. [新規登録] を選択します。
  4. アプリケーションの名前を入力します。 例: マイ テスト アプリケーション
  5. [サポートされているアカウントの種類] で、 [この組織のディレクトリ内のアカウントのみ] を選択します。
  6. [リダイレクト URI][プラットフォームの選択] ドロップダウンで [Web] を選び、[URL] テキスト ボックスに「https://jwt.ms」と入力します。
  7. [登録] を選んで、アプリの登録を完了します。

次のスクリーンショットは、"マイ テスト アプリケーション" の登録方法を示したものです。

Screenshot that shows how to select the supported account type and redirect URI.

3.1 アプリケーション ID を取得する

アプリの登録の [概要] で、[アプリケーション (クライアント) ID] をコピーします。 後の手順では、アプリ ID を {App_to_enrich_ID} として参照します。 Microsoft Graph では、appId プロパティによって参照されます。

Screenshot that shows how to copy the application ID.

3.2 暗黙的なフローを有効にする

jwt.ms テスト アプリケーションでは、暗黙的なフローを使います。 "マイ テスト アプリケーション" の登録で暗黙的なフローを有効にします。

  1. [管理] で、 [認証] を選択します。
  2. [暗黙的な許可およびハイブリッド フロー] で、[ID トークン (暗黙的およびハイブリッド フローに使用)] チェックボックスをオンにします。
  3. [保存] を選択します。

3.3 クレーム マッピング ポリシーに対してアプリを有効にする

カスタム認証拡張機能から返された属性から、トークンにマップされるものを選ぶには、クレーム マッピング ポリシーを使います。 トークンを拡張できるようにするには、アプリケーション登録によるマップされたクレームの受け入れを明示的に有効にする必要があります。

  1. "マイ テスト アプリケーション" の登録で、[管理][マニフェスト] を選びます。
  2. マニフェストで acceptMappedClaims 属性を見つけて、値を true に設定します。
  3. accessTokenAcceptedVersion2 に設定します。
  4. [保存] を選択して変更を保存します。

次の JSON スニペットでは、これらのプロパティを構成する方法を示します。

{
  "acceptMappedClaims": true,
  "accessTokenAcceptedVersion": 2,
  "appId": "22222222-0000-0000-0000-000000000000",
}

警告

マルチテナント アプリでは acceptMappedClaims プロパティを true に設定しないでください。悪意のある者がアプリのクレームマッピング ポリシーを作成することを許可してしまう場合があります。 代わりに、カスタム署名キーを構成します

手順 4: カスタム クレーム プロバイダーをアプリに割り当てる

カスタム認証拡張機能から受け取ったクレームでトークンが発行されるようにするには、カスタム クレーム プロバイダーをアプリケーションに割り当てる必要があります。 これはトークンの対象ユーザーに基づいているため、ID トークンで要求を受け取るにはクライアント アプリケーションにプロバイダーを割り当て、アクセス トークンで要求を受け取るにはリソース アプリケーションにプロバイダーを割り当てる必要があります。 カスタム クレーム プロバイダーは、トークン発行開始イベント リスナーで構成されたカスタム認証拡張機能に依存します。 カスタム クレーム プロバイダーからのクレームのすべてまたはサブセットのどちらを、トークンにマップするかを選択できます。

次の手順のようにして、マイ テスト アプリケーション とカスタム認証拡張機能を接続します。

最初に、カスタム認証拡張機能をカスタム クレーム プロバイダー ソースとして割り当てます。

  1. アプリケーション管理者以上の権限で Microsoft Entra 管理センターにサインインします。

  2. [ID]>[アプリケーション]>[Application registrations] (アプリケーションの登録) を参照します。

  3. [概要] ページの [ローカル ディレクトリでのマネージド アプリケーション] で、マイ テスト アプリケーションを選びます。

  4. [管理][シングル サインオン] を選びます。

  5. [属性とクレーム] で、[編集] を選びます。

    Screenshot that shows how to configure app claims.

  6. [詳細設定] メニューを展開します。

  7. [Custom claims provider] (カスタム クレーム プロバイダー)[構成] を選びます。

  8. [Custom claims provider] (カスタム クレーム プロバイダー) ドロップダウン ボックスを展開して、前に作成した "トークン発行イベント" を選びます。

  9. [保存] を選択します。

次に、カスタム クレーム プロバイダーから属性を割り当てます。これは、クレームとしてトークンに発行されている必要があります。

  1. [新しクレームの追加] を選んで、新しいクレームを追加します。 発行するクレームに名前を指定します (例: dateOfBirth)。

  2. [ソース]Attribute を選び、[ソース属性] ドロップダウン ボックスから customClaimsProvider.DateOfBirth を選びます。

    Screenshot that shows how to add a claim mapping to your app.

  3. [保存] を選択します。

  4. このプロセスを繰り返して、属性 customClaimsProvider.customRolescustomClaimsProvider.apiVersioncustomClaimsProvider.correlationId を追加できます。

手順 5: Azure 関数を保護する

Microsoft Entra カスタム認証拡張機能は、サーバー間フローを使って、HTTP の Authorization ヘッダーで Azure 関数に送信されるアクセス トークンを取得します。 関数を Azure に発行するときは、特に運用環境では、Authorization ヘッダーで送信されるトークンを検証する必要があります。

Azure 関数を保護するには、受信したトークンを Azure Functions 認証イベント API アプリケーション登録で検証するため、次の手順のようにして Azure AD 認証を統合します。

Note

Azure 関数アプリが、カスタム認証拡張機能が登録されているテナントとは異なる Azure テナントでホストされている場合は、「OpenID Connect ID プロバイダーの使用」ステップに進んでください。

  1. Azure portal にサインインします。

  2. 前に発行した関数アプリに移動して選択します。

  3. 左側のメニューで [認証] を選択します。

  4. [ID プロバイダーの追加] を選びます。

  5. ID プロバイダーとして [Microsoft] を選択します。

  6. [アプリの登録] ->[アプリ登録の種類][このディレクトリ内の既存のアプリ登録を選択] を選び、カスタム クレーム プロバイダーの登録時に前に作成した "Azure Functions 認証イベント API" アプリ登録を選びます。

  7. [Unauthenticated requests] (認証されていない要求) で、ID プロバイダーとして [HTTP 401 認可されていない] を選びます。

  8. [トークン ストア] オプションをオフにします。

  9. [追加] を選んで、Azure 関数に認証を追加します。

    Screenshot that shows how to add authentication to your function app.

5.1 OpenID Connect ID プロバイダーの使用

Microsoft ID プロバイダーを構成した場合は、このステップをスキップします。 そうではなく、カスタム認証拡張機能が登録されているテナントとは異なるテナントで Azure 関数がホストされている場合は、次の手順のようにして関数を保護します。

  1. Azure portal にサインインしてから、前に発行した関数アプリに移動して選択します。

  2. 左側のメニューで [認証] を選択します。

  3. [ID プロバイダーの追加] を選びます。

  4. ID プロバイダーとして [OpenID Connect] を選びます。

  5. Contoso Microsoft Entra ID などの名前を指定します。

  6. [メタデータ エントリ] で、[ドキュメントの URL] に次の URL を入力します。 {tenantId} を Microsoft Entra テナント ID に置き換えます。

    https://login.microsoftonline.com/{tenantId}/v2.0/.well-known/openid-configuration
    
  7. [アプリの登録] で、前に作成した "Azure Functions 認証イベント API" アプリ登録のアプリケーション ID (クライアント ID) を入力します。

  8. Microsoft Entra 管理センターで次の手順を実行します。

    1. 前に作成した "Azure Functions 認証イベント API" アプリの登録を選択します。
    2. [証明書とシークレット]>[クライアント シークレット]>[新しいクライアント シークレット] の順に選択します。
    3. クライアント シークレットの説明を追加します。
    4. シークレットの有効期限を選択するか、カスタムの有効期間を指定します。
    5. [追加] を選択します。
    6. クライアント アプリケーションのコードで使用できるように、シークレットの値を記録しておきます。 このページからの移動後は、このシークレットの値は "二度と表示されません"。
  9. Azure 関数に戻り、[アプリの登録][クライアント シークレット] を入力します。

  10. [トークン ストア] オプションをオフにします。

  11. [追加] を選んで、OpenID Connect ID プロバイダーを追加します。

手順 6: アプリケーションをテストする

カスタム クレーム プロバイダーをテストするには、次の手順のようにします。

  1. 新しいプライベート ブラウザーを開き、次の URL に移動してサインインします。

    https://login.microsoftonline.com/{tenant-id}/oauth2/v2.0/authorize?client_id={App_to_enrich_ID}&response_type=id_token&redirect_uri=https://jwt.ms&scope=openid&state=12345&nonce=12345
    
  2. {tenant-id} は、テナント ID、テナント名、または検証済みドメイン名の 1 つに置き換えます。 たとえば、「 contoso.onmicrosoft.com 」のように入力します。

  3. {App_to_enrich_ID} は、マイ テスト アプリケーションの登録 ID に置き換えます。

  4. ログインすると、https://jwt.ms でデコードされたトークンが表示されます。 Azure 関数からのクレームがデコードされたトークンで提示されていることを確認します (例: dateOfBirth)。

次の手順