Azure Functions でマネージド コネクタを使用する

マネージドコネクターを使用することで、Microsoft 365、Microsoft Teams、SharePoint、多くのサードパーティシステムなどのサービスで、ウェブフックセットアップコードを書いたりOAuthトークンを管理したりせずに、イベントや呼び出し操作に対応できます。 Azure FunctionsはAzure Connector Namespaceと連携し、トリガーとSDKを提供します。これにより、ビジネスロジックに集中できる一方で、コネクタの名前空間はウェブフック、認証、再試行を担当します。

Note

Azure Functions 向け Azure Connector Namespace の統合は現在パブリック プレビューです。 機能、構成名、特定のマネージドコネクタのサポートは、一般公開(GA)前に変更されることがあります。 この機能の使用には、Microsoft Azure プレビューの使用条件が適用されます。

現在サポートされているのはC#、Node.js、Python言語スタックのみです。

コネクターが機能を強化する方法

コネクターネームスペースは、関数プログラミングモデルに2つの機能を追加します:

  • コネクタトリガー
    関数は、Microsoft 365の新しいメール、SharePointに追加されたファイル、Teamsに投稿されたメッセージなど、外部サービスでイベントが発生すると実行されます。 ランタイムはコネクターネームスペースからウェブフックのコールバックを受け取る connectorTrigger バインディングを公開します。
  • コネクタSDKアクション
    関数コードはSDKクライアントを通じてコネクタ操作を呼び出します。 SDKはMicrosoft 365 Outlook、Microsoft 365ユーザー、Teams、SharePoint、OneDriveなどのマネージドコネクタをカバーしています。 まだSDKモデルを持っていないマネージドコネクタはHTTPエンドポイントとして呼び出せます。

マネージドコネクタは、HTTP、タイマー、キュー、Service Bus、Event Grid、Durable Functionsなどのクラシックな関数トリガーやバインディングと併用できます。

プレビューの可用性

ディメンション 可用性
コネクターネームスペース領域 アメリカ西中部(westcentralus)。
機能アプリはどの対応地域でも設置可能です。
言語 .NET 10/.NET 8 孤立、Python 3.13+、Node.js 22+(JS/TS)。 Java、PowerShell、Goはサポートされていません。
開催計画 Flex Consumption (推奨)、 PremiumDedicatedContainer Apps
Pricing 標準関数の価格:プレビュー中にコネクタトリガー/SDKに追加料金はありません。
コネクターネームスペースは別々の請求があります。

コネクタを使用する場合

複雑なカスタムロジックを実行するよりも、関数が主に外部サービスとやり取りする必要がある場合はコネクターを使いましょう。 関数アプリでマネージドコネクタを使う方法を考えてみてください:

  • 外部の出来事に反応する
    アプリは外部接続サービスから発生するイベント(新しいメール、カレンダー招待、ファイル、リスト項目、Teamsのアクティビティ)を処理しなければなりませんが、ウェブフックの登録、ハンドシェイクの検証、OAuthの更新に手間をかけたくはありません。 例えば、あなたの関数が監視されたOffice 365 Outlookフォルダ内の新しいメールを処理し、メッセージを分類し、Office 365 コネクタに呼びかけて充実させ、メールにフラグを付けたり移動したりするケースを考えてみてください。 これらすべての分散作業はアプリで行われ、リフレッシュトークンはコネクターの名前空間で処理されます。

  • カスタムサービスクライアントの置き換え
    関数コードはすでにカスタムHTTPクライアントを使ってMicrosoft 365やサードパーティAPIを呼び出しており、多くの接続でシークレット、スコープ、再試行ポリシーを管理する必要があり、すぐにメンテナンスの負担になります。 代わりに、プラグインSDK内の型付きクライアントを関数コード内で直接使い、マネージドコネクターが接続処理を任せることもできます。

  • 既存のアプリの展開を活用しましょう
    すでに展開パイプラインとモニタリングツールを備えたイベント駆動型の機能アプリプロジェクトを構築していますね。 マネージドコネクターを使って、同じプロジェクト内で新しい外部サービストリガーベースの機能を追加し、既存のインフラを活用できます。 例えば、以前はメッセージキューやLogic Appsに依存していた関数型アプリが、今ではTeamsの活動に直接反応し、組織内のチェックやマネージャーの検索のためにOffice 365に接続できるようになりました。

  • エージェント ワークフロー
    関数がイベントを受け取り、AIモデルと理性処理し、コネクタ操作を通じて外部サービスに応答するワークフローを構築しています。 サーバーレスエージェントのランタイムを活用して、マネージドコネクタベースのトリガーやマネージドコネクタSDKを活用しながら、エージェントワークフローをプログラムできます。

  • 管理統合によるコードファースト制御
    マネージドコネクターは外部サービスとのインバウンドおよびアウトバウンド通信を簡素化したいですが、コードファーストのプログラミングモデルと、分岐、ステップ間の認証管理、既存ライブラリの再利用などオーケストレーションの完全なコントロールを好みます。

    Tip

    ワークロードがカスタム コードを含まないコネクタ間の純粋なオーケストレーションのみである場合、Logic Apps Standard は引き続き最もシンプルな選択肢です。 詳細については、「他のAzure統合オプションとの関係」をご覧ください。

他のAzure統合オプションとの関係

Azure Functions のマネージド コネクタは追加機能です。 最適な選択は、ワークロードに必要なカスタムコードの量と、チームがビジュアルデザイナーを好むかコードのどちらを好むかによります。

オプション 最適なシナリオ 次のものが得られます…
Logic Apps Standard コネクタ間のワークフローのオーケストレーション;チームはビジュアルデザイナーを好みます。ステップ間に少しだけカスタムコードを付けていました。 同じコネクタエコシステム向けのローコードデザイナーです。
マネージド コネクタを使用した Azure Functions カスタムブランチ、プロセス中のライブラリ、その他のバインディング、トリガーとアクション間のAIモデル呼び出しなど、コードファーストの体験を提供します。 .NET、Python、または Node.js の著作;機能展開と監視;外部サービス用のウェブフックやOAuthコードは使いません。
サービスSDKを用いたHTTPトリガー 対象サービス用のマネージドコネクタが存在しない場合や、コネクタが提供していないプロトコルレベルの制御が必要な場合です。 認証、再試行、ウェブフック検証の完全な制御;コネクターネームスペースの要件はありません。

1 つの関数アプリで、3 つのパターンをすべて組み合わせることができます。 コネクタ トリガーを既存の HTTP トリガー アプリに追加し、SDK クライアントを段階的に導入できます。

パッケージと前提条件

各対応言語には、トリガーバインディングとコネクタSDKクライアントを取り込む少数のパッケージがあります。

ワーカー拡張パッケージにはコネクタトリガーバインディングが付属しています。 Azure.Connectors.Sdk.*パッケージ(コネクタごとに1つ)はタイプ付きペイロードとSDKクライアントを出荷します。

dotnet add package Microsoft.Azure.Functions.Worker.Extensions.Connector --prerelease
dotnet add package Azure.Connectors.Sdk --prerelease

.NET分離ワーカーの場合は、net8.0 または net10.0 と最新の Functions worker をターゲットとします。

Pythonは、プレビュー拡張機能バンドルを使用して、型指定されたOffice 365 モデルのトリガー バインドと azurefunctions-extensions-connectors パッケージを読み込みます。 バンドルを host.jsonに追加します。

{
    "version": "2.0",
    "extensionBundle": {
        "id": "Microsoft.Azure.Functions.ExtensionBundle.Preview",
        "version": "[4.42.0, 5.0.0)"
    }
}

ランタイム パッケージと拡張機能パッケージをインストールします。

pip install "azure-functions>=2.2.0b4"
pip install azurefunctions-extensions-connectors

@app.connector_triggerデコレーターはすべての管理型コネクターに対応しています。 型指定されたペイロード モデルは、 azurefunctions-extensions-connectors パッケージを通じて積極的に開発および追加されています。 型付きモデルのないマネージドコネクタでは、ペイロードを文字列として扱います。

Node.js は、実験用拡張機能バンドルを使用してトリガー バインドを読み込みます。 バンドルを host.jsonに追加します。

{
    "version": "2.0",
    "extensionBundle": {
        "id": "Microsoft.Azure.Functions.ExtensionBundle.Preview",
        "version": "[4.42.0, 5.0.0)"
    }
}

Functions ライブラリとコネクタ パッケージをインストールします。

npm install @azure/functions
npm install @azure/functions-extensions-connectors
npm install @azure/connectors

型付きモデルが存在する場合は、 @azure/functions-extensions-connectors (例: connectors.office365.onNewEmail)で型入りエントリーポイントを活用してください。 生のペイロードを扱いたいときは、マネージドコネクターに app.connectorTrigger from @azure/functions を使うと良いでしょう。

Javaと PowerShell は、パブリック プレビューではサポートされていません。 現在サポートされているランタイムのリストについては プレビューの提供 状況をご覧ください。

コネクタベースのトリガー

管理型コネクタベースのトリガーは、接続されたサービスでイベントが発生すると関数を実行します。 コネクタ名前空間は、コネクタ拡張のウェブフックエンドポイントを使ってHTTPS経由で関数アプリにイベントを届けます。

POST /runtime/webhooks/connector?functionName={FunctionName}&code={connector_extension_key}

{FunctionName} は、[Function] 属性内の名前と一致します。 {connector_extension_key} は、実行によって取得するシステムキーの数値です:

{FunctionName} は、あなたの @app.function_name デコレーター内の名前と一致します。 {connector_extension_key} は、実行によって取得するシステムキーの数値です:

{FunctionName} は、トリガー登録で指定した名前と一致します。 {connector_extension_key} は、実行によって取得するシステムキーの数値です:

az functionapp keys list \
    --resource-group <resource-group> \
    --name <function-app> \
    --query "systemKeys.connector_extension" \
    --output tsv

コネクターの名前空間内のトリガー設定はそのコールバックURLを保存し、各コールバックでシステムキーを表示します。 Functionsランタイムは関数を実行する前にキーを検証します。 共有シークレットがない環境では、関数アプリの前にApp Serviceの組み込み認証を配置し、コネクターの名前空間からマネージドIDトークンを検証できます。 完全なパターンについては.NETのサンプル:マネージドIDを用いた組み込み認証をご覧ください。

Tip

プレビュー期間中は、コネクタによってトリガーされる関数に Flex 従量課金プランを使用します。 Flex Consumption は、コネクタ プラットフォームの認証モデルに合わせたインスタンスごとのスケールとマネージド ID のサポートを提供します。

要求ペイロードには、イベント本文に加えて、トリガー構成、接続、イベントの種類、関連付け ID を識別する一連の x-ms-* ヘッダーが含まれます。 マネージドコネクターがSDKモデルを持つ場合、ランタイムはペイロードをそのモデルに直接デシリアライズします。 クライアントSDKを持たないマネージドコネクタの場合、関数は生のJSONボディを受け取ります。

次の例は、新しい電子メールが Office 365 Outlook メールボックスに到着したときに発生する関数を示しています。 トリガー登録は言語ごとです。コネクタ名前空間内のトリガー構成はすべての場合で同じです。

using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Extensions.Connector;
using Azure.Connectors.Sdk.Office365.Models;
using Microsoft.Extensions.Logging;

public class OnNewEmail
{
    private readonly ILogger<OnNewEmail> _logger;

    public OnNewEmail(ILogger<OnNewEmail> logger) => _logger = logger;

    [Function("OnNewEmail")]
    public IActionResult Run(
        [ConnectorTrigger()] Office365OnNewEmailTriggerPayload payload)
    {
        var emails = payload?.Body?.Value ?? [];
        foreach (var email in emails)
        {
            _logger.LogInformation(
                "Received email from {From} with subject '{Subject}'.",
                email.From, email.Subject);
        }

        return new OkResult();
    }
}

Office365OnNewEmailTriggerPayload モデルとその他の操作ペイロードの種類は、Azure.Connectors.Sdk.Office365.Models から取得されます。 オペレーションからペイロードへの完全なマッピングについては、Operations to Azure Functionsシグネチャマッピングを参照してください。

import azure.functions as func
import json
import logging

app = func.FunctionApp()

@app.function_name(name="OnNewEmail")
@app.connector_trigger(arg_name="payload")
def on_new_email(payload: str) -> None:
    data = json.loads(payload)
    emails = data.get("body", {}).get("value", [])
    for email in emails:
        logging.info(
            "Received email from %s with subject '%s'.",
            email.get("from"), email.get("subject"))

特に Office 365 の OnNewEmailV3 操作については、azurefunctions-extensions-connectors の型指定されたデコレーターを使用できます:

import azure.functions as func
import azurefunctions.extensions.connectors.office365 as office365
import logging

app = func.FunctionApp()

@app.function_name(name="OnNewEmail")
@app.connector_trigger(arg_name="email")
def on_new_email(email: office365.ClientReceiveMessage) -> None:
    logging.info(
        "Received email from %s with subject '%s'.",
        email.from_, email.subject)
import { InvocationContext } from '@azure/functions';
import {
    connectors,
    EmailTriggerContext,
} from '@azure/functions-extensions-connectors';

connectors.office365.onNewEmail('OnNewEmail', {
    handler: async (
        context: EmailTriggerContext,
        invocationContext: InvocationContext,
    ) => {
        for (const email of context.emails) {
            invocationContext.log(
                `Received email from '${email.from}' with subject '${email.subject}'.`,
            );
        }
    },
});

入力されたエントリ ポイントがまだないコネクタの場合は、app.connectorTrigger の汎用的な @azure/functions を使用します。

import { app, InvocationContext } from '@azure/functions';

app.connectorTrigger('OnNewItem', {
    handler: async (payload: unknown, context: InvocationContext) => {
        const data = typeof payload === 'string' ? JSON.parse(payload) : payload;
        const items: Record<string, unknown>[] = (data as any)?.body?.value ?? [];
        for (const item of items) {
            context.log(`Item ID: ${item.Id}`);
        }
    },
});

コネクタ トリガーは、パブリック プレビューではこの言語では使用できません。

コネクターの名前空間でトリガー設定は、Azure CLI、ARM、またはBicepを使って作成します。 このステップはコネクタープラットフォームの一部であり、コネクターのコンテンツセットに文書化されています。 関数には、トリガー登録用の独自の構成コマンドは付属していません。

関数をコネクターの名前空間に認証してください

Note

このセクションでは、コネクタ名前空間とあなたの関数アプリ間の認証について説明しています。 コネクターネームスペースがアップストリームサービス(Microsoft 365、Teams、SharePoint)にどのように認証されるかについては、Azureコネクターの概要をご覧ください。

デフォルトの認証モデルでは、コネクターの名前空間が各コールバックで提示する共有システムキー(connector_extension)を使用します。 ただし、共有キーはトリガーごとにスコープ設定できず、関数アプリとコネクタの名前空間間で協調的にローテーションする必要があります。 本番ワークロードでは、代わりに管理型IDを用いた App Service内蔵認証 (Easy Authとも呼ばれる)を使用します。

このパターンでは、コネクターネームスペースはシステム割り当てまたはユーザー割り当ての管理IDを用いて、各コールバックごとにEntra IDトークンを要求します。 関数アプリは、要求が Functions ホストに到達する前に、対象ユーザー、発行者、呼び出し元のオブジェクト ID を含むトークンを検証します。 共有キーなし、クライアント シークレットなし、どこでも。

エンドツーエンドの動作例については、このリポジトリを参照してください: functions-connectors-net-builtinauth

関数アプリの構成

組み込みの認証は、Functions ランタイムが要求を受け取る前に、App Service ワーカー境界で実行されます。 authsettingsV2 ARM プロパティまたは Bicep での同等のプロパティを使用して構成します。

Setting Purpose
requireAuthentication: true 有効なトークンがない要求を拒否します (401 を返します)。
identityProviders.azureActiveDirectory.enabled: true Entra ID トークンを検証します
registration.clientId 搭載認証がトークンの検証を行う、Entra アプリ登録のアプリ (クライアント) ID。
registration.openIdIssuer お使いのテナントの発行元 URL: https://login.microsoftonline.com/{tenantId}/v2.0
validation.allowedAudiences Entra アプリのクライアント ID と識別子 URI。 トークンの aud クレームには、これらのオーディエンスのいずれか 1 つが含まれている必要があります。
validation.defaultAuthorizationPolicy.allowedPrincipals.identities 関数の呼び出しが許可されているマネージド ID のオブジェクト (プリンシパル) ID。 ここに記載すべきはコネクターネームスペースのマネージドIDのみです。 異なる oid 要求を持つトークンは、403 を取得します。

関数アプリには、 Entra アプリ登録にフェデレーションされたユーザー割り当てマネージド ID も必要です。 組み込み認証では、その フェデレーション ID 資格情報 (FIC) を使用して、クライアント シークレットを格納せずに Entra アプリのクライアント アサーションを作成します。 この bicep パターンでは、ユーザーが割り当てた MI のクライアント ID を保持するアプリ設定に clientSecretSettingName を設定し、搭載認証機能に対してシークレットの代わりに FIC を使用するように指示します。

組み込みの認証がすでにすべてのリクエストを検証しているため、 host.jsonで冗長なシステムキーチェックを無効にできます。これは次のJSON断片のように見えます。

{
    ...
    "extensions": {
        "connector": {
            "system": {
                "webhookAuthorizationLevel": "Anonymous"
            }
        }
    }
}

コネクターネームスペースの設定

コネクターの名前空間には、システム割り当てまたはユーザー割り当てのマネージドアイデンティティが有効かつアタッチされている必要があります。 トリガー設定を作成する際、ユーザー割り当てのアイデンティティに対して authentication.type = ManagedServiceIdentityauthentication.identity = <resource-id-of-managed-identity> を指定するか、システム割り当てのアイデンティティに対して identity を省略してください。 また、コネクタ ランタイムがトークン内でどのオーディエンスを要求すべきかを認識できるように、authentication.audience = <entra-app-client-id> も指定してください。

コネクタランタイムは、その管理されたアイデンティティを利用して、毎回のコールバックでEntra IDトークンを生成します。 このトークンでは、 iss (発行者)がテナント、 aud (オーディエンス)がEntraアプリのクライアントID、 oid (オブジェクトID)がアイデンティティの主IDです。 組み込み認証では、3 つすべてが検証されます。

コネクターネームスペースリソースも、 office365 接続などの接続へのアクセスを必要とします。 管理されたアイデンティティのプリンシパルIDを一覧にするアクセスポリシーを通じてこのアクセスを許可します。 サンプルのbicepファイルは、名前空間の識別子と接続アクセスポリシーの両方の完全な構成を示しています。

適用される内容

組み込み認証では、トークンが次の順序で検証されます。

  1. トークンの存在 - トークンが見つからないか期限切れ→ 401
  2. 署名 - お使いのテナント向けの発行者の JWKS を使用して検証済み
  3. iss (発行者) - openIdIssuer と一致する必要があります
  4. aud (対象ユーザー) - 参加している必要があります allowedAudiences
  5. oid (オブジェクト/プリンシパル ID) - allowedPrincipals.identitiesのいずれかの ID と一致する必要があります。 その他の ID → 403

このチェックはApp Serviceエッジで行われるため、関数コードはコネクタ名前空間のマネージドIDから来ていないリクエストを決して認識しません。 アクセスチェックには申請コードは必要ありません。

認証フロー

┌─────────────────────────────────────────────────────────────────┐
│  Connector namespace  (westcentralus)                           │
│  • System-assigned or user-assigned managed identity enabled    │
│  • Trigger config: authentication.type = ManagedServiceIdentity │
│                    authentication.audience = <Entra app ID>     │
│                    callbackUrl = https://<func>/runtime/…       │
└────────────────────────┬───────────────────────────────────────┘
                         │
                         │  POST callbackUrl
                         │  Authorization: Bearer <AAD token>
                         │     iss = your tenant
                         │     aud = Entra app clientId
                         │     oid = managed identity principalId
                         ▼
┌──────────────────────────────────────────────────────────────┐
│  Function App  (any region)                                  │
│                                                              │
│   ┌──────────────────────────────────────────────────────┐   │
│   │ Built-in authentication  (App Service edge)          │   │
│   │   • Validates signature, iss, aud, exp               │   │
│   │   • Checks oid ∈ allowedPrincipals.identities        │   │
│   │   → No token  → 401                                  │   │
│   │   → Wrong oid → 403                                  │   │
│   └────────────────────┬─────────────────────────────────┘   │
│                        │ pass                                │
│                        ▼                                     │
│   ┌──────────────────────────────────────────────────────┐   │
│   │ /runtime/webhooks/connector                          │   │
│   │   (webhookAuthorizationLevel = Anonymous)            │   │
│   └────────────────────┬─────────────────────────────────┘   │
│                        ▼                                     │
│   ┌──────────────────────────────────────────────────────┐   │
│   │ Your function(payload)                               │   │
│   └──────────────────────────────────────────────────────┘   │
└──────────────────────────────────────────────────────────────┘
                         ▲
                         │ FIC (federated identity credential)
         ┌───────────────┴────────────────┐
         │  Entra app registration         │
         │  (federated to function-app MI) │
         └─────────────────────────────────┘

コードでのコネクタの使用

コネクタSDKは、関数がコネクタ操作をアウトバウンドアクションとして呼び出すことを可能にします。 クライアントサーフェスはトリガーが使用するコネクタ名空間内の同じ基盤となるマネージドコネクタを使用しているため、単一のマネージドコネクタで同じサービスアカウントのインバウンドトリガーとアウトバウンドコールの両方を駆動できます。

.NETでは、各コネクタは型指定されたクライアント (たとえば、Office365ClientOffice365UsersClientTeamsClient) を Azure.Connectors.Sdk.{Service} に出荷します。 クライアントのコンストラクタは接続のランタイムURLと認証情報を受け取ります。

次のパターンは、エンド ツー エンドの電子メール ユーザー参照 Teams サンプルからのものです。

using Azure.Core;
using Azure.Identity;
using Azure.Connectors.Sdk.Office365;
using Azure.Connectors.Sdk.Office365Users;
using Azure.Connectors.Sdk.Teams;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

var credential = new DefaultAzureCredential(new DefaultAzureCredentialOptions
{
    ManagedIdentityClientId = Environment.GetEnvironmentVariable("AZURE_CLIENT_ID")
});

var host = new HostBuilder()
    .ConfigureFunctionsWebApplication()
    .ConfigureServices(services =>
    {
        services.AddSingleton<TokenCredential>(credential);

        services.AddSingleton(sp => new Office365Client(
            new Uri(Environment.GetEnvironmentVariable("OFFICE365_CONNECTION_RUNTIME_URL")!),
            sp.GetRequiredService<TokenCredential>()));

        services.AddSingleton(sp => new Office365UsersClient(
            new Uri(Environment.GetEnvironmentVariable("OFFICE365USERS_CONNECTION_RUNTIME_URL")!),
            sp.GetRequiredService<TokenCredential>()));

        services.AddSingleton(sp => new TeamsClient(
            new Uri(Environment.GetEnvironmentVariable("TEAMS_CONNECTION_RUNTIME_URL")!),
            sp.GetRequiredService<TokenCredential>()));
    })
    .Build();

host.Run();

*_CONNECTION_RUNTIME_URL設定はコネクターの名前空間上の各接続ごとのランタイムエンドポイントを指しています。 クライアントを関数に挿入し、 UserProfileAsyncGetEmailsAsyncFlagAsyncなどの型指定されたメソッドを呼び出します。 コネクタ以外のトリガー (Teams に投稿する HTTP トリガーなど) から SDK クライアントを呼び出すこともできます。

Python で、型付きクライアント向けに azure-connectors をインストールします(たとえば、office365teamsoffice365Users)。 クライアントは、接続ごとのランタイム URL と資格情報を受け入れます。 SDKのアクションカバレッジは拡大しています。

Node.js では、型付きクライアント用に @azure/connectors をインストールします(たとえば、office365teamsoffice365Users)。 クライアントは、接続ごとのランタイム URL と資格情報を受け入れます。 SDKのアクションカバレッジは拡大しています。

コネクタSDKはこれらの言語では公開プレビューでは利用できません。