C# で電子メールを送信するためのグラフ API アクセス トークンを取得して使用する方法

Azure

Microsoft Graph API のアクセス トークン取得の合理化

毎日、Graph Explorer からアクセス トークンを手動で取得する必要があり、不便に感じたことはありますか?特に、Microsoft Graph API 経由で電子メールを送信する自動化に依存している多忙なチームの一員である場合は、イライラすることがあります。手動プロセスはすぐに生産性のボトルネックになる可能性があります。 🤔

これを簡素化するために、チームのアクセス トークンを自動的に取得する Azure 関数を構築することにしました。このソリューションにより、反復的なタスクの必要性がなくなり、誰もがトークン管理ではなく本来の業務に集中できるようになります。それはワークフローに待望のカフェインを強化するようなものです。 ☕

ただし、ほとんどの開発の過程と同様に、この開発にも課題がなかったわけではありません。トークンは正常に生成されましたが、関数によって返されたトークンが Graph Explorer から返されたトークンと一致しないという障害に遭遇しました。この予期せぬ不一致により、その有効性と機能についていくつかの疑問が生じました。

この記事では、私が使用したコード、発生した問題、および問題のトラブルシューティングのために実行した手順を共有します。同様の機能を構築している場合でも、Azure と Graph API に興味がある場合でも、このガイドでは実践的な洞察と関連性のある例を示してプロセスを説明します。飛び込んでみましょう! 🚀

指示 使用例
FormUrlEncodedContent この C# コマンドは、application/x-www-form-urlencoded 形式でエンコードされたデータを含む POST リクエストのリクエスト本文を作成するために使用されます。これにより、この形式を必要とする API へのキーと値のペアの受け渡しが簡素化されます。
HttpResponseMessage C# の HTTP リクエストから受信した応答を表します。これにより、サーバーの応答のステータス、ヘッダー、内容を確認できます。
EnsureSuccessStatusCode HTTP 応答ステータス コードが成功 (2xx) であることを確認するメソッド。そうでない場合は例外がスローされるため、エラー処理が簡単になります。
JsonConvert.DeserializeObject<T> この Newtonsoft.Json メソッドは、JSON 文字列を C# オブジェクトまたは動的型に解析するために使用されます。これは、API 応答からアクセス トークンを抽出するために重要です。
os.getenv 環境変数を取得する Python メソッド。これは、クライアント ID やシークレットなどの機密データに安全にアクセスするために不可欠です。
requests.post HTTP POST リクエストを送信する Python メソッド。ここでは、必要なペイロードを使用して Microsoft Graph API トークン エンドポイントを呼び出すために使用されます。
raise Exception エラーが発生したときに明示的に例外を発生させる Python コマンド。これは、API 応答が成功しなかった場合のエラー処理に使用されます。
Environment.GetEnvironmentVariable この C# メソッドは環境変数を取得します。これにより、資格情報をソース コードにハードコードせずに資格情報にアクセスするための安全な方法が提供されます。
dynamic 実行時に型が解決されるオブジェクトの作成を可能にする C# キーワード。予測できない構造を持つ JSON 応答を処理する場合に便利です。
httpClient.PostAsync 非同期 HTTP POST リクエストを送信するための C# メソッド。ここでは、Microsoft Identity のトークン エンドポイントを呼び出すために使用されます。

グラフ API トークン取得の理解と最適化

Microsoft Graph API を使用して電子メールを送信するプロセスを自動化するために、最初のスクリプトは、C# の クライアント資格情報フロー を使用してアクセス トークンを取得する方法を示しています。これは、ユーザーの操作が必要ない、Azure Function などのサーバー側のアプリケーションやサービスを構築する場合に特に便利です。スクリプトは、「ClientId」、「ClientSecret」、「TenantId」などの機密データを保存するための環境変数を使用して、トークンを安全に取得します。これにより、ソース コード内でハードコードされた資格情報が回避され、セキュリティが確保されます。

ソリューションの中核は、認証に必要な形式でリクエスト ペイロードを作成する「FormUrlEncodedContent」クラスを中心に展開します。ペイロードの準備が完了すると、「httpClient.PostAsync」メソッドは HTTP POST 要求を Microsoft ID トークン エンドポイントに送信します。この呼び出しにより、アプリは有効なトークンをプログラムで取得できるようになり、そのトークンを使用して Microsoft Graph API などのリソースにアクセスし、電子メールの送信やデータの管理を行うことができます。

Python の例は、トークン取得のための軽量の代替手段を提供することで C# スクリプトを補完します。 「os.getenv」メソッドを利用することで、C# スクリプトと同様に、機密の資格情報を環境から直接取得します。 「requests.post」関数はトークンエンドポイント呼び出しを実行し、Python に精通した開発者にとってプロセスを簡素化します。どちらのスクリプトにも、「response.EnsureSuccessStatusCode」 (C#) による堅牢なエラー処理と、認証失敗や API エラーなどの問題を管理するための Python での明示的な例外発生 (「raise Exception」) が含まれています。

これらのスクリプトを適用する実際の例としては、次の締め切りやサービス停止などの重要なイベントについてチーム メンバーに電子メールを送信する チーム通知システム が挙げられます。毎日 Graph Explorer にログインして手動でトークンを取得する代わりに、これらのスクリプトによってプロセスが自動化され、人的エラーが削減され、効率が向上します。 🚀 この自動化は時間を節約するだけでなく、営業時間外であってもシステムがシームレスに動作することを保証します。エンタープライズ レベルのソリューションとの統合のために C# を選択するか、シンプルさのために Python を選択するかにかかわらず、どちらのアプローチでも核心的な問題に効果的に対処できます。 😊

C# で Microsoft Graph API のアクセス トークンを取得する

このソリューションは、C# のモジュール式の安全なバックエンド スクリプトを使用して、Microsoft Graph API トークンをプログラム的に取得して処理します。

// Import necessary namespaces
using System;
using System.Net.Http;
using System.Threading.Tasks;
using System.Collections.Generic;
using Newtonsoft.Json;
using Microsoft.Extensions.Logging;
namespace GraphApiTokenFetcher
{
    public class TokenService
    {
        private static readonly HttpClient httpClient = new HttpClient();
        // Fetch access token using Client Credentials flow
        public static async Task<string> GetGraphAccessTokenAsync(ILogger log)
        {
            try
            {
                // Retrieve environment variables
                var clientId = Environment.GetEnvironmentVariable("ClientId");
                var clientSecret = Environment.GetEnvironmentVariable("ClientSecret");
                var tenantId = Environment.GetEnvironmentVariable("TenantId");
                var tokenEndpoint = $"https://login.microsoftonline.com/{tenantId}/oauth2/v2.0/token";
                // Prepare the request body
                var body = new FormUrlEncodedContent(new[]
                {
                    new KeyValuePair<string, string>("client_id", clientId),
                    new KeyValuePair<string, string>("scope", "https://graph.microsoft.com/.default"),
                    new KeyValuePair<string, string>("client_secret", clientSecret),
                    new KeyValuePair<string, string>("grant_type", "client_credentials")
                });
                // Make the HTTP POST request
                HttpResponseMessage response = await httpClient.PostAsync(tokenEndpoint, body);
                response.EnsureSuccessStatusCode();
                // Read and parse the response
                string responseContent = await response.Content.ReadAsStringAsync();
                var tokenResult = JsonConvert.DeserializeObject<dynamic>(responseContent);
                return tokenResult.access_token;
            }
            catch (Exception ex)
            {
                log.LogError($"Error fetching Graph API token: {ex.Message}");
                throw;
            }
        }
    }
}

単純な Python スクリプトを使用したトークン取得のテスト

このアプローチでは、代替バックエンド ソリューションの「requests」ライブラリを使用して、Python でトークンを取得および検証する方法を示します。

# Import required libraries
import os
import requests
import json
# Function to fetch access token
def get_graph_access_token():
    client_id = os.getenv("ClientId")
    client_secret = os.getenv("ClientSecret")
    tenant_id = os.getenv("TenantId")
    token_endpoint = f"https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/token"
    # Prepare request payload
    payload = {
        "client_id": client_id,
        "client_secret": client_secret,
        "scope": "https://graph.microsoft.com/.default",
        "grant_type": "client_credentials"
    }
    # Send the POST request
    response = requests.post(token_endpoint, data=payload)
    if response.status_code == 200:
        return response.json().get("access_token")
    else:
        raise Exception(f"Failed to retrieve token: {response.text}")
# Retrieve and print token
if __name__ == "__main__":
    try:
        token = get_graph_access_token()
        print("Access Token:", token)
    except Exception as e:
        print("Error:", str(e))

グラフ API トークン検証における課題の克服

Microsoft Graph API を使用する場合、開発者がよく直面する重要な課題の 1 つは、アクセス トークンの 有効性と範囲 を確保することです。クライアント資格情報フローを使用してトークンを取得するのは簡単ですが、その使いやすさは、Azure AD でアプリケーションに付与されているアクセス許可によって異なります。よくある見落としは、API 権限を正しく構成できず、トークンを使用して電子メールを送信したり、その他のアクションを実行したりするときにエラーが発生することです。

もう 1 つの重要な考慮事項は、Graph Explorer を通じて取得されたトークンとプログラムで生成されたトークンの違いを理解することです。 Graph Explorer トークンは通常、ユーザーのコンテキストとその特定の権限に関連付けられていますが、クライアント資格情報フローを使用するプログラム トークンはアプリケーション スコープです。この違いは、基になる構成が似ているように見えても、返されたトークンが一致しない理由を説明しています。

これらの不一致をトラブルシューティングするには、アプリケーションに必要な Mail.Send または Azure portal で同等の委任されたアクセス許可があることを確認する必要があります。さらに、[JWT.io](https://jwt.io) のようなツールを使用してデコードされたトークン ペイロードを検査すると、「scp」 (スコープ) や「ロール」などの欠落しているクレームや間違ったクレームを特定するのに役立ちます。これが重要となる実際のシナリオは、クライアント通知のための一括電子メール配信を自動化することです。適切な構成がないと、運用中にシステムに障害が発生し、顧客の通信に影響を与える可能性があります。これらの手順を実行すると、シームレスな統合が保証され、ソリューションの信頼性が構築されます。 😊

  1. 私のトークンが Graph Explorer のトークンと一致しないのはなぜですか?
  2. プログラムで取得されたトークンは、 これは、Graph Explorer のユーザーベースのトークンとは異なり、アクセス許可の範囲をアプリケーションに限定します。
  3. の役割は何ですか トークンリクエストのパラメータは?
  4. の API アクセス レベルを指定します。たとえば、 、適切なアクセス許可を確保します。
  5. アクセス トークンをデコードするにはどうすればよいですか?
  6. 次のようなツールを使用します トークンのペイロードを検査して「scp」や「roles」などのクレームを調べ、権限を検証します。
  7. トークンを使用すると「Bad Request」応答が返されるのはなぜですか?
  8. アプリに必要な機能があることを確認してください (例えば。、 ) Azure AD で構成され、管理者の同意が付与されています。
  9. トークンを自動的に更新できますか?
  10. はい、有効期限が切れたときに、次のコマンドを使用して新しいトークンをプログラムで取得できます。 手動介入の必要性を回避します。

トークンの取得を自動化することで、 、開発者は時間を節約し、安全でエラーのないプロセスを保証できます。この方法は、手動介入なしでリソースに確実にアクセスする必要があるサーバー側アプリケーションに特に役立ちます。 😊

トークンのスコープ、権限、ユーザー トークンとアプリ トークンの違いを理解することは、成功するために非常に重要です。これらの洞察があれば、自信を持って効率的なワークフローを実装し、中断を最小限に抑え、チームや組織の生産性を向上させることができます。

  1. に関する包括的なガイド Microsoft Graph API認証 クライアント認証情報のフロー、スコープ、権限について説明します。
  2. に関する公式ドキュメント .NET での HttpClient の使用法 、非同期 HTTP リクエストの例を含みます。
  3. からの洞察 JWT.io Microsoft Graph API 認証で使用される JSON Web トークン (JWT) のデコードと検証用。
  4. 詳細なチュートリアル Azure Active Directory アプリの登録 API 権限とクライアント シークレットを構成します。