次の方法で共有


Azure Functions でトークン発行開始イベント用の REST API を作成する

この記事では、Azure portal で Azure Functions を使用してトークン発行開始イベント を含む REST API を作成する方法について説明します。 Azure 関数アプリと、トークンの追加要求を返すことができる HTTP トリガー関数を作成します。

前提条件

  • カスタム認証拡張機能の概要に関する記事で説明されている概念の基本的な理解。
  • Azure Functions を作成できる Azure サブスクリプション。 既存の Azure アカウントをお持ちでない場合は、無料試用版にサインアップするか、アカウントを作成するときに Visual Studio Subscription のベネフィットを利用できます。
  • Microsoft Entra ID テナント。 この攻略ガイドには、顧客または従業員のどちらかのテナントを使用できます。

この記事では、Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents NuGet ライブラリを使用して、トークン発行開始イベント用の REST API を作成する方法について説明します。 Visual Studio または Visual Studio Code で HTTP トリガー関数を作成し、それを認証用に構成し、さらに Azure portal にデプロイします。この関数は、Azure Functions を介してアクセスできます。

前提条件

Note

Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents NuGet ライブラリは現在プレビュー段階です。 この記事の手順は変更される可能性があります。 トークン発行開始イベントを実装する一般提供の実装については、Azure portal を使用して行うことができます。

Azure 関数アプリの作成

HTTP トリガー関数の作成を続行する前に、Azure portal で Azure 関数アプリとそれに関連付けられているリソースを作成します。

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

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

  3. [関数アプリ] を検索して選択し、[作成] を選択します。

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

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

  6. デプロイされたら、[リソースに移動] を選択して、新しい関数アプリを確認します。

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

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

  1. 関数アプリの [概要] ページで、[関数] ペインを選択し、[Azure portal で作成] の下にある [関数の作成] を選択します。
  2. [関数の作成] ウィンドウで、[開発環境] プロパティは [Develop in portal] (ポータルで開発) のままにします。 [テンプレート] の下にある [HTTP トリガー] を選択します。
  3. [テンプレートの詳細] で、[新しい関数] プロパティに「CustomAuthenticationExtensionsAPI」と入力します。
  4. [認証レベル][関数] を選びます。
  5. [作成] を選択します 開発環境とテンプレートを選ぶ方法を示すスクリーンショット。

関数を編集する

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

  1. メニューから、[開発者] の下にある [コードとテスト] を選択します。

  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 Microsoft Entra request    
        string correlationId = data?.data.authenticationContext.correlationId;
    
        // Claims to return to Microsoft Entra
        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>();
        }
    }
    
  3. 上部のメニューから [関数の URL の取得] を選択し、URL の値をコピーします。 この関数 URL は、カスタム認証拡張機能を設定するときに使用できます。

Azure 関数アプリの作成とビルド

このステップでは、お使いの IDE を使用して HTTP トリガー関数 API を作成し、必要な NuGet パッケージをインストールし、サンプル コードでコピーします。 プロジェクトをビルドし、関数をローカルで実行して関数の URL を抽出します。

アプリケーションを作成する

Azure 関数アプリを作成するには、次のステップを実行します。

  1. Visual Studio を開き、 [新しいプロジェクトの作成] を選択します。
  2. Azure Functions」を検索して選択し、[次へ] を選択します。
  3. プロジェクトに "AuthEventsTrigger" などの名前を付けます。 ソリューション名とプロジェクト名を一致させることをお勧めします。
  4. プロジェクトの 場所 を選択します。 [次へ] を選択します。
  5. ターゲット フレームワークとして [.NET 6.0 (長期サポート)] を選択します。
  6. 関数の種類として [http トリガー]を選択し、[承認レベル][関数] に設定されるように選択します。 [作成] を選択します
  7. ソリューション エクスプローラーで、Function1.cs ファイルの名前を AuthEventsTrigger.cs に変更し、名前変更の提案をそのまま使用します。

NuGet パッケージのインストールとプロジェクトのビルド

プロジェクトを作成したら、必要な NuGet パッケージをインストールし、プロジェクトをビルドする必要があります。

  1. Visual Studio の上部メニューで、[プロジェクト] を選択し、次に [NuGet パッケージの管理] を選択します。
  2. [参照] タブを選択し、右のウィンドウで [Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents] を検索して選択します。 [インストール] を選択します。
  3. 表示されるポップアップで変更を適用し、承認します。

サンプル コードを追加する

関数 API は、トークンに対する追加クレームのソースです。 この記事では、サンプル アプリの値をハードコーディングしています。 運用環境では、外部データ ストアからユーザーに関する情報を取り込むことができます。 既存のプロパティについては、WebJobsAuthenticationEventsContext クラスに関する記事を参照してください。

AuthEventsTrigger.cs ファイルでは、内容全体を次のコードに置き換えます。

using System;
using Microsoft.Azure.WebJobs;
using Microsoft.Extensions.Logging;
using Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents.TokenIssuanceStart;
using Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents;

namespace AuthEventsTrigger
{
    public static class AuthEventsTrigger
    {
        [FunctionName("onTokenIssuanceStart")]
        public static WebJobsAuthenticationEventResponse Run(
            [WebJobsAuthenticationEventsTrigger] WebJobsTokenIssuanceStartRequest request, ILogger log)
        {
            try
            {
                // Checks if the request is successful and did the token validation pass
                if (request.RequestStatus == WebJobsAuthenticationEventsRequestStatusType.Successful)
                {
                    // Fetches information about the user from external data store
                    // Add new claims to the token's response
                    request.Response.Actions.Add(
                        new WebJobsProvideClaimsForToken(
                            new WebJobsAuthenticationEventsTokenClaim("dateOfBirth", "01/01/2000"),
                            new WebJobsAuthenticationEventsTokenClaim("customRoles", "Writer", "Editor"),
                            new WebJobsAuthenticationEventsTokenClaim("apiVersion", "1.0.0"),
                            new WebJobsAuthenticationEventsTokenClaim(
                                "correlationId", 
                                request.Data.AuthenticationContext.CorrelationId.ToString())));
                }
                else
                {
                    // If the request fails, such as in token validation, output the failed request status, 
                    // such as in token validation or response validation.
                    log.LogInformation(request.StatusMessage);
                }
                return request.Completed();
            }
            catch (Exception ex) 
            { 
                return request.Failed(ex);
            }
        }
    }
}

プロジェクトをローカルで構築して実行する

プロジェクトが作成され、サンプル コードが追加されました。 お使いの IDE を使用して、プロジェクトをローカルでビルドして実行し、ローカル関数の URL を抽出する必要があります。

  1. 上部のメニューで [ビルド] に移動し、[ソリューションのビルド] を選択します。
  2. F5 を押すか、上部メニューから [AuthEventsTrigger] を選択して関数を実行します。
  3. [関数の URL] を、関数の実行時にポップアップ表示されるターミナルからコピーします。 これは、カスタム認証拡張機能を設定するときに使用できます。

Azure にデプロイする前に、関数をローカルでテストすることをお勧めします。 Microsoft Entra ID が REST API に送信する要求を模倣したダミーの JSON 本文を使用できます。 お好みの API テスト ツールを使用して、関数を直接呼び出します。

  1. お使いの IDE で local.settings.json を開き、コードを次の JSON に置き換えます。 ローカル テストの目的で、"AuthenticationEvents__BypassTokenValidation"true に設定できます。

    {
      "IsEncrypted": false,
      "Values": {
        "AzureWebJobsStorage": "",
        "AzureWebJobsSecretStorageType": "files",
        "FUNCTIONS_WORKER_RUNTIME": "dotnet",
        "AuthenticationEvents__BypassTokenValidation" : true
      }
    }
    
  2. 好みの API テスト ツールを使用して、新しい HTTP 要求を作成し、HTTP メソッドPOST に設定します。

  3. Microsoft Entra ID から REST API に送信される要求を模倣する次の JSON 本文を使用します。

    {
        "type": "microsoft.graph.authenticationEvent.tokenIssuanceStart",
        "source": "/tenants/aaaabbbb-0000-cccc-1111-dddd2222eeee/applications/00001111-aaaa-2222-bbbb-3333cccc4444",
        "data": {
            "@odata.type": "microsoft.graph.onTokenIssuanceStartCalloutData",
            "tenantId": "aaaabbbb-0000-cccc-1111-dddd2222eeee",
            "authenticationEventListenerId": "11112222-bbbb-3333-cccc-4444dddd5555",
            "customAuthenticationExtensionId": "22223333-cccc-4444-dddd-5555eeee6666",
            "authenticationContext": {
                "correlationId": "aaaa0000-bb11-2222-33cc-444444dddddd",
                "client": {
                    "ip": "127.0.0.1",
                    "locale": "en-us",
                    "market": "en-us"
                },
                "protocol": "OAUTH2.0",
                "clientServicePrincipal": {
                    "id": "aaaaaaaa-0000-1111-2222-bbbbbbbbbbbb",
                    "appId": "00001111-aaaa-2222-bbbb-3333cccc4444",
                    "appDisplayName": "My Test application",
                    "displayName": "My Test application"
                },
                "resourceServicePrincipal": {
                    "id": "aaaaaaaa-0000-1111-2222-bbbbbbbbbbbb",
                    "appId": "00001111-aaaa-2222-bbbb-3333cccc4444",
                    "appDisplayName": "My Test application",
                    "displayName": "My Test application"
                },
                "user": {
                    "companyName": "Casey Jensen",
                    "createdDateTime": "2023-08-16T00:00:00Z",
                    "displayName": "Casey Jensen",
                    "givenName": "Casey",
                    "id": "00aa00aa-bb11-cc22-dd33-44ee44ee44ee",
                    "mail": "casey@contoso.com",
                    "onPremisesSamAccountName": "Casey Jensen",
                    "onPremisesSecurityIdentifier": "<Enter Security Identifier>",
                    "onPremisesUserPrincipalName": "Casey Jensen",
                    "preferredLanguage": "en-us",
                    "surname": "Jensen",
                    "userPrincipalName": "casey@contoso.com",
                    "userType": "Member"
                }
            }
        }
    }
    
    
  4. [送信] を選択すると、次のような JSON 応答が表示されます。

    {
        "data": {
            "@odata.type": "microsoft.graph.onTokenIssuanceStartResponseData",
            "actions": [
                {
                    "@odata.type": "microsoft.graph.tokenIssuanceStart.provideClaimsForToken",
                    "claims": {
                        "customClaim1": "customClaimValue1",
                        "customClaim2": [
                            "customClaimString1",
                            "customClaimString2" 
                        ]
                    }
                }
    
            ]
        }
    }
    

関数のデプロイと Azure への発行

この関数は、IDE を使用して Azure にデプロイする必要があります。 関数を発行できるように、Azure アカウントに正しくサインインしていることを確認します。

  1. ソリューション エクスプローラーでプロジェクトを右クリックし、[発行] を選択します。

  2. [ターゲット][Azure] を選択し、[次へ] を選択します。

  3. [特定のターゲット][Azure 関数アプリ (Windows)] を選択して、[Azure 関数アプリ (Windows)]を選択し、[次へ] を選択します。

  4. [関数インスタンス][サブスクリプション名] ドロップダウンを使用して、新しい関数アプリを作成するサブスクリプションを選択します。

  5. 新しい関数アプリを発行する場所を選択し、[新規作成] を選択します。

  6. 関数アプリ (Windows)」ページで、次の表に示すように関数アプリの設定を使用し、[作成] を選択します。

    設定 提案された値 Description
    名前 グローバルに一意の名前 新しい関数アプリを識別する名前。 有効な文字は、a-z (大文字と小文字の区別をしない)、0-9、および -です。
    サブスクリプション 該当するサブスクリプション この新しい関数アプリが作成されるサブスクリプション。
    リソース グループ myResourceGroup 既存のリソース グループを選択するか、関数アプリを作成する新しいリソース グループに名前を付けます。
    プランの種類 "従量課金 (サーバーレス)" 関数アプリにどのようにリソースが割り当てられるかを定義するホスティング プラン。
    場所 優先リージョン 自分の近く、または関数がアクセスできる他のサービスの近くのリージョンを選択します。
    Azure ストレージ ストレージ アカウント Functions の共通言語ランタイムでは、Azure ストレージ アカウントが必要です。 [新規] を選択して汎用ストレージ アカウントを構成します。
    Application Insights 既定値 Azure Monitor の機能。 これは自動選択です。使用するものを選択するか、新しいものを構成します。
  7. 関数アプリがデプロイされるまでしばらく待ちます。 ウィンドウが閉じたら、[完了] を選択します。

  8. 新しい [発行] ウィンドウが開きます。 上部にある [発行] を選択します。 関数アプリがデプロイされ、Azure portal に表示されるまで数分待ちます。

Azure 関数の認証を構成する

Azure 関数の認証を設定するには、次の 3 つの方法があります。

既定では、環境変数を使用してコードを Azure portal での認証用に設定します。 次のタブを使用して、環境変数を実装する方法を選択するか、または組み込みの「Azure アプリ サービスの認証と承認」を参照してください。 環境変数を設定する場合は、次の値を使用します。

名前
AuthenticationEvents__AudienceAppId トークン発行イベントのカスタム要求プロバイダーの構成」で設定したカスタム認証拡張機能アプリ ID
AuthenticationEvents__AuthorityUrl • ワークフォース テナント https://login.microsoftonline.com/<tenantID>
• 外部テナント https://<mydomain>.ciamlogin.com/<tenantID>
AuthenticationEvents__AuthorizedPartyAppId 99045fe1-7639-4a75-9d4a-577b6ca3810f または別の承認されたパーティ

環境変数を使用して Azure portal で認証を設定する

  1. アプリケーション管理者および認証管理者以上の権限で Azure portal にサインインします。
  2. 作成した関数アプリに移動し、[設定][構成] を選択します。
  3. [アプリケーション設定]で、[新しいアプリケーション設定] を選択し、次の環境変数および関連する値を追加します。
  4. [保存] を選択して、アプリケーション設定を保存します。

次のステップ